diff --git a/Core/Export/SampleToPython.cpp b/Core/Export/SampleToPython.cpp
index 9b31c0b0da85db3ce972d095cb17c00ceb3c2c45..34876ba035700de7d5ab9b4bb758dc78d9fa2a51 100644
--- a/Core/Export/SampleToPython.cpp
+++ b/Core/Export/SampleToPython.cpp
@@ -445,11 +445,10 @@ std::string SampleToPython::defineInterferenceFunctions() const
 
         } else if (const auto* iff =
                        dynamic_cast<const InterferenceFunctionFinite2DLattice*>(interference)) {
-            const Lattice2D& lattice = iff->lattice();
+            const auto* lattice = INodeUtils::OnlyChildOfType<Lattice2D>(*iff);
+
             result << indent() << it->second << " = ba.InterferenceFunctionFinite2DLattice("
-                   << pyfmt::printNm(lattice.length1()) << ", " << pyfmt::printNm(lattice.length2())
-                   << ", " << pyfmt::printDegrees(lattice.latticeAngle()) << ", "
-                   << pyfmt::printDegrees(lattice.rotationAngle()) << ", "
+                   << m_label->labelLattice2D(lattice) << ", "
                    << iff->numberUnitCells1() << ", " << iff->numberUnitCells2() << ")\n";
 
             if (iff->integrationOverXi() == true)
diff --git a/Sample/Aggregate/InterferenceFunctionFinite2DLattice.cpp b/Sample/Aggregate/InterferenceFunctionFinite2DLattice.cpp
index f53a35ef17af12e3549b6f187bf285e6d11ec889..342e1e2c8514b2794ac810bf11e1b1933f3ac734 100644
--- a/Sample/Aggregate/InterferenceFunctionFinite2DLattice.cpp
+++ b/Sample/Aggregate/InterferenceFunctionFinite2DLattice.cpp
@@ -36,21 +36,6 @@ InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(const L
     registerChild(m_lattice.get());
 }
 
-//! Constructor of two-dimensional finite lattice interference function.
-//! @param length_1: length of first lattice vector in nanometers
-//! @param length_2: length of second lattice vector  in nanometers
-//! @param alpha: angle between lattice vectors in radians
-//! @param xi: rotation of lattice with respect to x-axis (beam direction) in radians
-//! @param N_1: number of lattice cells in the first lattice direction
-//! @param N_2: number of lattice cells in the second lattice direction
-InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1,
-                                                                         double length_2,
-                                                                         double alpha, double xi,
-                                                                         unsigned N_1, unsigned N_2)
-    : InterferenceFunctionFinite2DLattice(BasicLattice(length_1, length_2, alpha, xi), N_1, N_2)
-{
-}
-
 InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice() = default;
 
 InterferenceFunctionFinite2DLattice* InterferenceFunctionFinite2DLattice::clone() const
diff --git a/Sample/Aggregate/InterferenceFunctionFinite2DLattice.h b/Sample/Aggregate/InterferenceFunctionFinite2DLattice.h
index 6f90b1fac3e1b11e5b0ad3a930d6bb051cf3bf59..35c24acdbbc42b64a43ea6d53dfe767a560e0190 100644
--- a/Sample/Aggregate/InterferenceFunctionFinite2DLattice.h
+++ b/Sample/Aggregate/InterferenceFunctionFinite2DLattice.h
@@ -25,8 +25,6 @@ class InterferenceFunctionFinite2DLattice : public IInterferenceFunction
 {
 public:
     InterferenceFunctionFinite2DLattice(const Lattice2D& lattice, unsigned N_1, unsigned N_2);
-    InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi,
-                                        unsigned N_1, unsigned N_2);
     ~InterferenceFunctionFinite2DLattice() final;
 
     InterferenceFunctionFinite2DLattice* clone() const override final;
diff --git a/auto/Wrap/doxygenSample.i b/auto/Wrap/doxygenSample.i
index 24e85c227a8eefca820fde4d372e6c26afe34c13..6ecaf52b6b71e43a085da58072f90bddb4dd8b99 100644
--- a/auto/Wrap/doxygenSample.i
+++ b/auto/Wrap/doxygenSample.i
@@ -4051,32 +4051,6 @@ N_2:
 number of lattice cells in the second lattice direction 
 ";
 
-%feature("docstring")  InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)
-
-Constructor of two-dimensional finite lattice interference function.
-
-Parameters:
------------
-
-length_1: 
-length of first lattice vector in nanometers
-
-length_2: 
-length of second lattice vector in nanometers
-
-alpha: 
-angle between lattice vectors in radians
-
-xi: 
-rotation of lattice with respect to x-axis (beam direction) in radians
-
-N_1: 
-number of lattice cells in the first lattice direction
-
-N_2: 
-number of lattice cells in the second lattice direction 
-";
-
 %feature("docstring")  InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice() final
 ";
 
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index 4034c9d9161d02e0e62aad455ca5d15ec0fae5ef..e942762598199d822e1ba4a703563ca84955d87b 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -7441,28 +7441,18 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
+    def __init__(self, lattice, N_1, N_2):
         r"""
         __init__(InterferenceFunctionFinite2DLattice self, Lattice2D lattice, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice
-        __init__(InterferenceFunctionFinite2DLattice self, double length_1, double length_2, double alpha, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice
-        InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)
+        InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(const Lattice2D &lattice, unsigned N_1, unsigned N_2)
 
         Constructor of two-dimensional finite lattice interference function.
 
         Parameters:
         -----------
 
-        length_1: 
-        length of first lattice vector in nanometers
-
-        length_2: 
-        length of second lattice vector in nanometers
-
-        alpha: 
-        angle between lattice vectors in radians
-
-        xi: 
-        rotation of lattice with respect to x-axis (beam direction) in radians
+        lattice: 
+        object specifying a 2d lattice structure
 
         N_1: 
         number of lattice cells in the first lattice direction
@@ -7471,7 +7461,7 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
         number of lattice cells in the second lattice direction 
 
         """
-        _libBornAgainSample.InterferenceFunctionFinite2DLattice_swiginit(self, _libBornAgainSample.new_InterferenceFunctionFinite2DLattice(*args))
+        _libBornAgainSample.InterferenceFunctionFinite2DLattice_swiginit(self, _libBornAgainSample.new_InterferenceFunctionFinite2DLattice(lattice, N_1, N_2))
     __swig_destroy__ = _libBornAgainSample.delete_InterferenceFunctionFinite2DLattice
 
     def clone(self):
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index cceff942b3260b843e732f760ceb7f5a719df2a7..4d8985022f3c91eb2ffe4c16edc0e2a6b58b4c65 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -53815,7 +53815,7 @@ SWIGINTERN PyObject *InterferenceFunction3DLattice_swiginit(PyObject *SWIGUNUSED
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Lattice2D *arg1 = 0 ;
   unsigned int arg2 ;
@@ -53826,9 +53826,10 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(PyObj
   int ecode2 = 0 ;
   unsigned int val3 ;
   int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
   InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "new_InterferenceFunctionFinite2DLattice", 3, 3, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "Lattice2D const &""'"); 
@@ -53855,145 +53856,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double arg4 ;
-  unsigned int arg5 ;
-  unsigned int arg6 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  unsigned int val5 ;
-  int ecode5 = 0 ;
-  unsigned int val6 ;
-  int ecode6 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
-  
-  if ((nobjs < 6) || (nobjs > 6)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  ecode5 = SWIG_AsVal_unsigned_SS_int(swig_obj[4], &val5);
-  if (!SWIG_IsOK(ecode5)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "5"" of type '" "unsigned int""'");
-  } 
-  arg5 = static_cast< unsigned int >(val5);
-  ecode6 = SWIG_AsVal_unsigned_SS_int(swig_obj[5], &val6);
-  if (!SWIG_IsOK(ecode6)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "6"" of type '" "unsigned int""'");
-  } 
-  arg6 = static_cast< unsigned int >(val6);
-  result = (InterferenceFunctionFinite2DLattice *)new InterferenceFunctionFinite2DLattice(arg1,arg2,arg3,arg4,arg5,arg6);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[7] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "new_InterferenceFunctionFinite2DLattice", 0, 6, argv))) SWIG_fail;
-  --argc;
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_unsigned_SS_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_unsigned_SS_int(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(self, argc, argv);
-        }
-      }
-    }
-  }
-  if (argc == 6) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            {
-              int res = SWIG_AsVal_unsigned_SS_int(argv[4], NULL);
-              _v = SWIG_CheckState(res);
-            }
-            if (_v) {
-              {
-                int res = SWIG_AsVal_unsigned_SS_int(argv[5], NULL);
-                _v = SWIG_CheckState(res);
-              }
-              if (_v) {
-                return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(self, argc, argv);
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_InterferenceFunctionFinite2DLattice'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(Lattice2D const &,unsigned int,unsigned int)\n"
-    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double,double,double,double,unsigned int,unsigned int)\n");
-  return 0;
-}
-
-
 SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionFinite2DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
@@ -73183,26 +73045,16 @@ static PyMethodDef SwigMethods[] = {
 	 { "InterferenceFunction3DLattice_swigregister", InterferenceFunction3DLattice_swigregister, METH_O, NULL},
 	 { "InterferenceFunction3DLattice_swiginit", InterferenceFunction3DLattice_swiginit, METH_VARARGS, NULL},
 	 { "new_InterferenceFunctionFinite2DLattice", _wrap_new_InterferenceFunctionFinite2DLattice, METH_VARARGS, "\n"
-		"InterferenceFunctionFinite2DLattice(Lattice2D lattice, unsigned int N_1, unsigned int N_2)\n"
-		"new_InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice\n"
-		"InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)\n"
+		"new_InterferenceFunctionFinite2DLattice(Lattice2D lattice, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice\n"
+		"InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(const Lattice2D &lattice, unsigned N_1, unsigned N_2)\n"
 		"\n"
 		"Constructor of two-dimensional finite lattice interference function.\n"
 		"\n"
 		"Parameters:\n"
 		"-----------\n"
 		"\n"
-		"length_1: \n"
-		"length of first lattice vector in nanometers\n"
-		"\n"
-		"length_2: \n"
-		"length of second lattice vector in nanometers\n"
-		"\n"
-		"alpha: \n"
-		"angle between lattice vectors in radians\n"
-		"\n"
-		"xi: \n"
-		"rotation of lattice with respect to x-axis (beam direction) in radians\n"
+		"lattice: \n"
+		"object specifying a 2d lattice structure\n"
 		"\n"
 		"N_1: \n"
 		"number of lattice cells in the first lattice direction\n"