diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index 31cff248f12d06ce35071b55d50cfad6583da4c8..424f019a2f55e014359d858c2aed27cbace1bc0a 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -4040,10 +4040,22 @@ class IDetector(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         r"""sizeOfRegionOfInterest(IDetector self) -> size_t"""
         return _libBornAgainDevice.IDetector_sizeOfRegionOfInterest(self)
 
+    def hasExplicitRegionOfInterest(self):
+        r"""hasExplicitRegionOfInterest(IDetector self) -> bool"""
+        return _libBornAgainDevice.IDetector_hasExplicitRegionOfInterest(self)
+
+    def axesClippedToRegionOfInterest(self):
+        r"""axesClippedToRegionOfInterest(IDetector self) -> CloneableVector< IAxis >"""
+        return _libBornAgainDevice.IDetector_axesClippedToRegionOfInterest(self)
+
     def regionOfInterestIndexToDetectorIndex(self, regionOfInterestIndex):
         r"""regionOfInterestIndexToDetectorIndex(IDetector self, size_t const regionOfInterestIndex) -> size_t"""
         return _libBornAgainDevice.IDetector_regionOfInterestIndexToDetectorIndex(self, regionOfInterestIndex)
 
+    def detectorIndexToRegionOfInterestIndex(self, detectorIndex):
+        r"""detectorIndexToRegionOfInterestIndex(IDetector self, size_t const detectorIndex) -> size_t"""
+        return _libBornAgainDevice.IDetector_detectorIndexToRegionOfInterestIndex(self, detectorIndex)
+
     def applyDetectorResolution(self, p_intensity_map):
         r"""
         applyDetectorResolution(IDetector self, IntensityData p_intensity_map)
@@ -4104,15 +4116,9 @@ class IDetector(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         """
         return _libBornAgainDevice.IDetector_numberOfSimulationElements(self)
 
-    def regionOfInterest(self):
-        r"""
-        regionOfInterest(IDetector self) -> RegionOfInterest const *
-        virtual const RegionOfInterest* IDetector::regionOfInterest() const =0
-
-        Returns region of interest if exists. 
-
-        """
-        return _libBornAgainDevice.IDetector_regionOfInterest(self)
+    def regionOfInterestBounds(self, iAxis):
+        r"""regionOfInterestBounds(IDetector self, size_t iAxis) -> pvacuum_double_t"""
+        return _libBornAgainDevice.IDetector_regionOfInterestBounds(self, iAxis)
 
 # Register IDetector in _libBornAgainDevice:
 _libBornAgainDevice.IDetector_swigregister(IDetector)
@@ -4191,16 +4197,6 @@ class IDetector2D(IDetector):
         """
         return _libBornAgainDevice.IDetector2D_maskAll(self)
 
-    def regionOfInterest(self):
-        r"""
-        regionOfInterest(IDetector2D self) -> RegionOfInterest const *
-        const RegionOfInterest * IDetector2D::regionOfInterest() const override
-
-        Returns region of interest if exists. 
-
-        """
-        return _libBornAgainDevice.IDetector2D_regionOfInterest(self)
-
     def setRegionOfInterest(self, xlow, ylow, xup, yup):
         r"""
         setRegionOfInterest(IDetector2D self, double xlow, double ylow, double xup, double yup)
@@ -4211,15 +4207,13 @@ class IDetector2D(IDetector):
         """
         return _libBornAgainDevice.IDetector2D_setRegionOfInterest(self, xlow, ylow, xup, yup)
 
-    def resetRegionOfInterest(self):
-        r"""
-        resetRegionOfInterest(IDetector2D self)
-        void IDetector2D::resetRegionOfInterest() override
-
-        Resets region of interest making whole detector plane available for the simulation. 
+    def regionOfInterestIndexToDetectorIndex(self, regionOfInterestIndex):
+        r"""regionOfInterestIndexToDetectorIndex(IDetector2D self, size_t const regionOfInterestIndex) -> size_t"""
+        return _libBornAgainDevice.IDetector2D_regionOfInterestIndexToDetectorIndex(self, regionOfInterestIndex)
 
-        """
-        return _libBornAgainDevice.IDetector2D_resetRegionOfInterest(self)
+    def detectorIndexToRegionOfInterestIndex(self, detectorIndex):
+        r"""detectorIndexToRegionOfInterestIndex(IDetector2D self, size_t const detectorIndex) -> size_t"""
+        return _libBornAgainDevice.IDetector2D_detectorIndexToRegionOfInterestIndex(self, detectorIndex)
 
     def active_indices(self):
         r"""
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index 91b85a4e1ee4baada1a66a13c34b399861b69528..4fd5ea54c921ba6affd823f05818c3d07b89a6f9 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -3145,72 +3145,71 @@ namespace Swig {
 #define SWIGTYPE_p_Rectangle swig_types[45]
 #define SWIGTYPE_p_RectangularDetector swig_types[46]
 #define SWIGTYPE_p_RectangularPixel swig_types[47]
-#define SWIGTYPE_p_RegionOfInterest swig_types[48]
-#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[49]
-#define SWIGTYPE_p_ScanResolution swig_types[50]
-#define SWIGTYPE_p_SimulationResult swig_types[51]
-#define SWIGTYPE_p_SphericalDetector swig_types[52]
-#define SWIGTYPE_p_VerticalLine swig_types[53]
-#define SWIGTYPE_p_allocator_type swig_types[54]
-#define SWIGTYPE_p_bool swig_types[55]
-#define SWIGTYPE_p_char swig_types[56]
-#define SWIGTYPE_p_const_iterator swig_types[57]
-#define SWIGTYPE_p_corr_matrix_t swig_types[58]
-#define SWIGTYPE_p_difference_type swig_types[59]
-#define SWIGTYPE_p_double swig_types[60]
-#define SWIGTYPE_p_first_type swig_types[61]
-#define SWIGTYPE_p_int swig_types[62]
-#define SWIGTYPE_p_iterator swig_types[63]
-#define SWIGTYPE_p_key_type swig_types[64]
-#define SWIGTYPE_p_long_long swig_types[65]
-#define SWIGTYPE_p_mapped_type swig_types[66]
-#define SWIGTYPE_p_p_ICoordSystem swig_types[67]
-#define SWIGTYPE_p_p_PyObject swig_types[68]
-#define SWIGTYPE_p_parameters_t swig_types[69]
-#define SWIGTYPE_p_second_type swig_types[70]
-#define SWIGTYPE_p_short swig_types[71]
-#define SWIGTYPE_p_signed_char swig_types[72]
-#define SWIGTYPE_p_size_type swig_types[73]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[74]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[75]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[76]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[77]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[78]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[79]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[80]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[81]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[82]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[83]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[84]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[85]
-#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[86]
-#define SWIGTYPE_p_std__invalid_argument swig_types[87]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[88]
-#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[89]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[90]
-#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[91]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[92]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[93]
-#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[94]
-#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[95]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[96]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[97]
-#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[98]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[99]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[100]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[101]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[102]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[103]
-#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[104]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[105]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[106]
-#define SWIGTYPE_p_unsigned_char swig_types[107]
-#define SWIGTYPE_p_unsigned_int swig_types[108]
-#define SWIGTYPE_p_unsigned_long_long swig_types[109]
-#define SWIGTYPE_p_unsigned_short swig_types[110]
-#define SWIGTYPE_p_value_type swig_types[111]
-static swig_type_info *swig_types[113];
-static swig_module_info swig_module = {swig_types, 112, 0, 0, 0, 0};
+#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[48]
+#define SWIGTYPE_p_ScanResolution swig_types[49]
+#define SWIGTYPE_p_SimulationResult swig_types[50]
+#define SWIGTYPE_p_SphericalDetector swig_types[51]
+#define SWIGTYPE_p_VerticalLine swig_types[52]
+#define SWIGTYPE_p_allocator_type swig_types[53]
+#define SWIGTYPE_p_bool swig_types[54]
+#define SWIGTYPE_p_char swig_types[55]
+#define SWIGTYPE_p_const_iterator swig_types[56]
+#define SWIGTYPE_p_corr_matrix_t swig_types[57]
+#define SWIGTYPE_p_difference_type swig_types[58]
+#define SWIGTYPE_p_double swig_types[59]
+#define SWIGTYPE_p_first_type swig_types[60]
+#define SWIGTYPE_p_int swig_types[61]
+#define SWIGTYPE_p_iterator swig_types[62]
+#define SWIGTYPE_p_key_type swig_types[63]
+#define SWIGTYPE_p_long_long swig_types[64]
+#define SWIGTYPE_p_mapped_type swig_types[65]
+#define SWIGTYPE_p_p_ICoordSystem swig_types[66]
+#define SWIGTYPE_p_p_PyObject swig_types[67]
+#define SWIGTYPE_p_parameters_t swig_types[68]
+#define SWIGTYPE_p_second_type swig_types[69]
+#define SWIGTYPE_p_short swig_types[70]
+#define SWIGTYPE_p_signed_char swig_types[71]
+#define SWIGTYPE_p_size_type swig_types[72]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[73]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[74]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[75]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[76]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[77]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[78]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[79]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[80]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[81]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[82]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[83]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[84]
+#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[85]
+#define SWIGTYPE_p_std__invalid_argument swig_types[86]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[87]
+#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[88]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[89]
+#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[90]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[91]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[92]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[93]
+#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[94]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[95]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[96]
+#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[97]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[98]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[99]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[100]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[101]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[102]
+#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[103]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[104]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[105]
+#define SWIGTYPE_p_unsigned_char swig_types[106]
+#define SWIGTYPE_p_unsigned_int swig_types[107]
+#define SWIGTYPE_p_unsigned_long_long swig_types[108]
+#define SWIGTYPE_p_unsigned_short swig_types[109]
+#define SWIGTYPE_p_value_type swig_types[110]
+static swig_type_info *swig_types[112];
+static swig_module_info swig_module = {swig_types, 111, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -36147,6 +36146,52 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IDetector_hasExplicitRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IDetector *arg1 = (IDetector *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  bool result;
+  
+  if (!args) SWIG_fail;
+  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_hasExplicitRegionOfInterest" "', argument " "1"" of type '" "IDetector const *""'"); 
+  }
+  arg1 = reinterpret_cast< IDetector * >(argp1);
+  result = (bool)((IDetector const *)arg1)->hasExplicitRegionOfInterest();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IDetector_axesClippedToRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IDetector *arg1 = (IDetector *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  SwigValueWrapper< CloneableVector< IAxis > > result;
+  
+  if (!args) SWIG_fail;
+  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_axesClippedToRegionOfInterest" "', argument " "1"" of type '" "IDetector const *""'"); 
+  }
+  arg1 = reinterpret_cast< IDetector * >(argp1);
+  result = ((IDetector const *)arg1)->axesClippedToRegionOfInterest();
+  resultobj = SWIG_NewPointerObj((new CloneableVector< IAxis >(static_cast< const CloneableVector< IAxis >& >(result))), SWIGTYPE_p_CloneableVectorT_IAxis_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IDetector_regionOfInterestIndexToDetectorIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
@@ -36177,6 +36222,36 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IDetector_detectorIndexToRegionOfInterestIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IDetector *arg1 = (IDetector *) 0 ;
+  size_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  size_t result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IDetector_detectorIndexToRegionOfInterestIndex", 2, 2, swig_obj)) SWIG_fail;
+  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_detectorIndexToRegionOfInterestIndex" "', argument " "1"" of type '" "IDetector const *""'"); 
+  }
+  arg1 = reinterpret_cast< IDetector * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IDetector_detectorIndexToRegionOfInterestIndex" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((IDetector const *)arg1)->detectorIndexToRegionOfInterestIndex(arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IDetector_applyDetectorResolution(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
@@ -36331,23 +36406,30 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IDetector_regionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IDetector_regionOfInterestBounds(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RegionOfInterest *result = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  std::pair< double,double > result;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
+  if (!SWIG_Python_UnpackTuple(args, "IDetector_regionOfInterestBounds", 2, 2, swig_obj)) SWIG_fail;
   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_regionOfInterest" "', argument " "1"" of type '" "IDetector const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector_regionOfInterestBounds" "', argument " "1"" of type '" "IDetector const *""'"); 
   }
   arg1 = reinterpret_cast< IDetector * >(argp1);
-  result = (RegionOfInterest *)((IDetector const *)arg1)->regionOfInterest();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RegionOfInterest, 0 |  0 );
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IDetector_regionOfInterestBounds" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((IDetector const *)arg1)->regionOfInterestBounds(arg2);
+  resultobj = swig::from(static_cast< std::pair< double,double > >(result));
   return resultobj;
 fail:
   return NULL;
@@ -36640,29 +36722,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IDetector2D_regionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IDetector2D *arg1 = (IDetector2D *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RegionOfInterest *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IDetector2D, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector2D_regionOfInterest" "', argument " "1"" of type '" "IDetector2D const *""'"); 
-  }
-  arg1 = reinterpret_cast< IDetector2D * >(argp1);
-  result = (RegionOfInterest *)((IDetector2D const *)arg1)->regionOfInterest();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RegionOfInterest, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IDetector2D_setRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector2D *arg1 = (IDetector2D *) 0 ;
@@ -36716,22 +36775,60 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IDetector2D_resetRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IDetector2D_regionOfInterestIndexToDetectorIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector2D *arg1 = (IDetector2D *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  PyObject *swig_obj[1] ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  size_t result;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
+  if (!SWIG_Python_UnpackTuple(args, "IDetector2D_regionOfInterestIndexToDetectorIndex", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IDetector2D, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector2D_resetRegionOfInterest" "', argument " "1"" of type '" "IDetector2D *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector2D_regionOfInterestIndexToDetectorIndex" "', argument " "1"" of type '" "IDetector2D const *""'"); 
   }
   arg1 = reinterpret_cast< IDetector2D * >(argp1);
-  (arg1)->resetRegionOfInterest();
-  resultobj = SWIG_Py_Void();
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IDetector2D_regionOfInterestIndexToDetectorIndex" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((IDetector2D const *)arg1)->regionOfInterestIndexToDetectorIndex(arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IDetector2D_detectorIndexToRegionOfInterestIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IDetector2D *arg1 = (IDetector2D *) 0 ;
+  size_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  size_t result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IDetector2D_detectorIndexToRegionOfInterestIndex", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IDetector2D, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector2D_detectorIndexToRegionOfInterestIndex" "', argument " "1"" of type '" "IDetector2D const *""'"); 
+  }
+  arg1 = reinterpret_cast< IDetector2D * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IDetector2D_detectorIndexToRegionOfInterestIndex" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((IDetector2D const *)arg1)->detectorIndexToRegionOfInterestIndex(arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
@@ -45589,7 +45686,10 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { "IDetector_sizeOfRegionOfInterest", _wrap_IDetector_sizeOfRegionOfInterest, METH_O, "IDetector_sizeOfRegionOfInterest(IDetector self) -> size_t"},
+	 { "IDetector_hasExplicitRegionOfInterest", _wrap_IDetector_hasExplicitRegionOfInterest, METH_O, "IDetector_hasExplicitRegionOfInterest(IDetector self) -> bool"},
+	 { "IDetector_axesClippedToRegionOfInterest", _wrap_IDetector_axesClippedToRegionOfInterest, METH_O, "IDetector_axesClippedToRegionOfInterest(IDetector self) -> CloneableVector< IAxis >"},
 	 { "IDetector_regionOfInterestIndexToDetectorIndex", _wrap_IDetector_regionOfInterestIndexToDetectorIndex, METH_VARARGS, "IDetector_regionOfInterestIndexToDetectorIndex(IDetector self, size_t const regionOfInterestIndex) -> size_t"},
+	 { "IDetector_detectorIndexToRegionOfInterestIndex", _wrap_IDetector_detectorIndexToRegionOfInterestIndex, METH_VARARGS, "IDetector_detectorIndexToRegionOfInterestIndex(IDetector self, size_t const detectorIndex) -> size_t"},
 	 { "IDetector_applyDetectorResolution", _wrap_IDetector_applyDetectorResolution, METH_VARARGS, "\n"
 		"IDetector_applyDetectorResolution(IDetector self, IntensityData p_intensity_map)\n"
 		"void IDetector::applyDetectorResolution(OutputData< double > *p_intensity_map) const\n"
@@ -45632,13 +45732,7 @@ static PyMethodDef SwigMethods[] = {
 		"Returns number of simulation elements. \n"
 		"\n"
 		""},
-	 { "IDetector_regionOfInterest", _wrap_IDetector_regionOfInterest, METH_O, "\n"
-		"IDetector_regionOfInterest(IDetector self) -> RegionOfInterest const *\n"
-		"virtual const RegionOfInterest* IDetector::regionOfInterest() const =0\n"
-		"\n"
-		"Returns region of interest if exists. \n"
-		"\n"
-		""},
+	 { "IDetector_regionOfInterestBounds", _wrap_IDetector_regionOfInterestBounds, METH_VARARGS, "IDetector_regionOfInterestBounds(IDetector self, size_t iAxis) -> pvacuum_double_t"},
 	 { "IDetector_swigregister", IDetector_swigregister, METH_O, NULL},
 	 { "IDetector2D_clone", _wrap_IDetector2D_clone, METH_O, "\n"
 		"IDetector2D_clone(IDetector2D self) -> IDetector2D\n"
@@ -45687,13 +45781,6 @@ static PyMethodDef SwigMethods[] = {
 		"Put the mask for all detector channels (i.e. exclude whole detector from the analysis) \n"
 		"\n"
 		""},
-	 { "IDetector2D_regionOfInterest", _wrap_IDetector2D_regionOfInterest, METH_O, "\n"
-		"IDetector2D_regionOfInterest(IDetector2D self) -> RegionOfInterest const *\n"
-		"const RegionOfInterest * IDetector2D::regionOfInterest() const override\n"
-		"\n"
-		"Returns region of interest if exists. \n"
-		"\n"
-		""},
 	 { "IDetector2D_setRegionOfInterest", _wrap_IDetector2D_setRegionOfInterest, METH_VARARGS, "\n"
 		"IDetector2D_setRegionOfInterest(IDetector2D self, double xlow, double ylow, double xup, double yup)\n"
 		"void IDetector2D::setRegionOfInterest(double xlow, double ylow, double xup, double yup)\n"
@@ -45701,13 +45788,8 @@ static PyMethodDef SwigMethods[] = {
 		"Sets rectangular region of interest with lower left and upper right corners defined. \n"
 		"\n"
 		""},
-	 { "IDetector2D_resetRegionOfInterest", _wrap_IDetector2D_resetRegionOfInterest, METH_O, "\n"
-		"IDetector2D_resetRegionOfInterest(IDetector2D self)\n"
-		"void IDetector2D::resetRegionOfInterest() override\n"
-		"\n"
-		"Resets region of interest making whole detector plane available for the simulation. \n"
-		"\n"
-		""},
+	 { "IDetector2D_regionOfInterestIndexToDetectorIndex", _wrap_IDetector2D_regionOfInterestIndexToDetectorIndex, METH_VARARGS, "IDetector2D_regionOfInterestIndexToDetectorIndex(IDetector2D self, size_t const regionOfInterestIndex) -> size_t"},
+	 { "IDetector2D_detectorIndexToRegionOfInterestIndex", _wrap_IDetector2D_detectorIndexToRegionOfInterestIndex, METH_VARARGS, "IDetector2D_detectorIndexToRegionOfInterestIndex(IDetector2D self, size_t const detectorIndex) -> size_t"},
 	 { "IDetector2D_active_indices", _wrap_IDetector2D_active_indices, METH_O, "\n"
 		"IDetector2D_active_indices(IDetector2D self) -> std::vector< size_t,std::allocator< size_t > >\n"
 		"std::vector< size_t > IDetector2D::active_indices() const\n"
@@ -46791,7 +46873,6 @@ static swig_type_info _swigt__p_RealLimits = {"_p_RealLimits", "RealLimits *", 0
 static swig_type_info _swigt__p_Rectangle = {"_p_Rectangle", "Rectangle *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RectangularDetector = {"_p_RectangularDetector", "RectangularDetector *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RectangularPixel = {"_p_RectangularPixel", "RectangularPixel *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_RegionOfInterest = {"_p_RegionOfInterest", "RegionOfInterest *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ResolutionFunction2DGaussian = {"_p_ResolutionFunction2DGaussian", "ResolutionFunction2DGaussian *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ScanResolution = {"_p_ScanResolution", "ScanResolution *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SimulationResult = {"_p_SimulationResult", "SimulationResult *", 0, 0, (void*)0, 0};
@@ -46905,7 +46986,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_Rectangle,
   &_swigt__p_RectangularDetector,
   &_swigt__p_RectangularPixel,
-  &_swigt__p_RegionOfInterest,
   &_swigt__p_ResolutionFunction2DGaussian,
   &_swigt__p_ScanResolution,
   &_swigt__p_SimulationResult,
@@ -47019,7 +47099,6 @@ static swig_cast_info _swigc__p_RealLimits[] = {  {&_swigt__p_RealLimits, 0, 0,
 static swig_cast_info _swigc__p_Rectangle[] = {  {&_swigt__p_Rectangle, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RectangularDetector[] = {  {&_swigt__p_RectangularDetector, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RectangularPixel[] = {  {&_swigt__p_RectangularPixel, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_RegionOfInterest[] = {  {&_swigt__p_RegionOfInterest, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ResolutionFunction2DGaussian[] = {  {&_swigt__p_ResolutionFunction2DGaussian, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ScanResolution[] = {  {&_swigt__p_ScanResolution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SimulationResult[] = {  {&_swigt__p_SimulationResult, 0, 0, 0},{0, 0, 0, 0}};
@@ -47133,7 +47212,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_Rectangle,
   _swigc__p_RectangularDetector,
   _swigc__p_RectangularPixel,
-  _swigc__p_RegionOfInterest,
   _swigc__p_ResolutionFunction2DGaussian,
   _swigc__p_ScanResolution,
   _swigc__p_SimulationResult,