diff --git a/GUI/Model/Sample/RoughnessItems.cpp b/GUI/Model/Sample/RoughnessItems.cpp
index 6fa1a071c006e6bdb7a0999267ac91f5c2609800..c08a49295313ace505e219a509ee608a268b2380 100644
--- a/GUI/Model/Sample/RoughnessItems.cpp
+++ b/GUI/Model/Sample/RoughnessItems.cpp
@@ -18,6 +18,8 @@
 namespace {
 namespace Tag {
 
+const QString BaseData("BaseData");
+const QString HeightDistributionModel("HeightDistributionModel");
 const QString Sigma("Sigma");
 const QString Hurst("Hurst");
 const QString LateralCorrelationLength("LateralCorrelationLength");
@@ -25,17 +27,29 @@ const QString LateralCorrelationLength("LateralCorrelationLength");
 } // namespace Tag
 } // namespace
 
-void RoughnessItem::writeTo(QXmlStreamWriter* w) const {}
+void RoughnessItem::writeTo(QXmlStreamWriter* w) const
+{
+    XML::writeTaggedElement(w, Tag::HeightDistributionModel, m_roughness_model);
+}
+
+void RoughnessItem::readFrom(QXmlStreamReader* r)
+{
+    while (r->readNextStartElement()) {
+        QString tag = r->name().toString();
 
-void RoughnessItem::readFrom(QXmlStreamReader* r) {}
+        if (tag == Tag::HeightDistributionModel)
+            XML::readTaggedElement(r, tag, m_roughness_model);
+        else
+            r->skipCurrentElement();
+    }
+}
 
 RoughnessItem::RoughnessItem()
 {
-    DefaultRoughness default_roughness_type;
     m_roughness_model.simpleInit("Interlayer profile",
                                  "Laterally averaged profile of the interlayer transition (or "
                                  "roughness height distribution)",
-                                 RoughnessModelCatalog::type(&default_roughness_type));
+                                 RoughnessModelCatalog::Type::Tanh);
 }
 
 //------------------------------------------------------------------------------------------------
@@ -54,6 +68,7 @@ BasicRoughnessItem::BasicRoughnessItem(double sigma, double hurst, double corr_l
 
 void BasicRoughnessItem::writeTo(QXmlStreamWriter* w) const
 {
+    XML::writeBaseElement<RoughnessItem>(w, Tag::BaseData, this);
     m_sigma.writeTo2(w, Tag::Sigma);
     m_hurst.writeTo2(w, Tag::Hurst);
     m_lateral_correlation_length.writeTo2(w, Tag::LateralCorrelationLength);
@@ -64,7 +79,9 @@ void BasicRoughnessItem::readFrom(QXmlStreamReader* r)
     while (r->readNextStartElement()) {
         QString tag = r->name().toString();
 
-        if (tag == Tag::Sigma)
+        if (tag == Tag::BaseData)
+            XML::readBaseElement<RoughnessItem>(r, tag, this);
+        else if (tag == Tag::Sigma)
             m_sigma.readFrom2(r, tag);
         else if (tag == Tag::Hurst)
             m_hurst.readFrom2(r, tag);
diff --git a/GUI/Model/Sample/RoughnessItems.h b/GUI/Model/Sample/RoughnessItems.h
index 99464546f039b1314ac2737223b3bc08a3a894bf..217642ef78e2dc783a202cb644f9b77b05334029 100644
--- a/GUI/Model/Sample/RoughnessItems.h
+++ b/GUI/Model/Sample/RoughnessItems.h
@@ -18,7 +18,7 @@
 #include "GUI/Model/Descriptor/DoubleProperty.h"
 #include "GUI/Model/Descriptor/PolyPtr.h"
 #include "GUI/Model/Sample/RoughnessCatalog.h"
-#include "Sample/Interface/RoughnessModels.h"
+#include "GUI/Model/Sample/RoughnessModelItems.h"
 
 class RoughnessItem {
 public:
@@ -28,16 +28,16 @@ public:
     virtual void readFrom(QXmlStreamReader* r);
     virtual DoubleProperties roughnessProperties() = 0;
 
-    PolyPtr<RoughnessModel, RoughnessModelCatalog>& roughnessModelSelection()
+    PolyPtr<RoughnessModelItem, RoughnessModelCatalog>& roughnessModelSelection()
     {
         return m_roughness_model;
     }
-    RoughnessModel* certainRoughnessModel() const { return m_roughness_model.certainItem(); }
-    void setRoughnessModelType(RoughnessModel* p) { m_roughness_model.setCertainItem(p); }
+    RoughnessModelItem* certainRoughnessModel() const { return m_roughness_model.certainItem(); }
+    void setRoughnessModelType(RoughnessModelItem* p) { m_roughness_model.setCertainItem(p); }
 
 protected:
     RoughnessItem();
-    PolyPtr<RoughnessModel, RoughnessModelCatalog> m_roughness_model;
+    PolyPtr<RoughnessModelItem, RoughnessModelCatalog> m_roughness_model;
 };
 
 class BasicRoughnessItem : public RoughnessItem {
diff --git a/GUI/Model/Sample/RoughnessModelItems.h b/GUI/Model/Sample/RoughnessModelItems.h
index db93879eadc2e73dc7e75590fc0dafec798151bb..dd9c56730061e3a0d90fee02e355882aa89a4876 100644
--- a/GUI/Model/Sample/RoughnessModelItems.h
+++ b/GUI/Model/Sample/RoughnessModelItems.h
@@ -16,17 +16,34 @@
 #define BORNAGAIN_GUI_MODEL_SAMPLE_ROUGHNESSMODELITEMS_H
 
 #include "Sample/Interface/RoughnessModels.h"
+#include <memory>
 
 class RoughnessModelItem {
 public:
     virtual ~RoughnessModelItem() = default;
 
-    virtual void writeTo(QXmlStreamWriter*) const = {};
-    virtual void readFrom(QXmlStreamReader*) = {};
+    virtual void writeTo(QXmlStreamWriter*) const {}
+    virtual void readFrom(QXmlStreamReader*) {}
+
+    virtual std::unique_ptr<RoughnessModel> createModel() const = 0;
+
+protected:
+    RoughnessModelItem() = default;
 };
 
-class ErfRoughnessItem : public RoughnessModelItem {};
+class ErfRoughnessItem : public RoughnessModelItem {
+public:
+    ErfRoughnessItem() = default;
+    std::unique_ptr<RoughnessModel> createModel() const { return std::make_unique<ErfRoughness>(); }
+};
 
-class TanhRoughnessItem : public RoughnessModelItem {};
+class TanhRoughnessItem : public RoughnessModelItem {
+public:
+    TanhRoughnessItem() = default;
+    std::unique_ptr<RoughnessModel> createModel() const
+    {
+        return std::make_unique<TanhRoughness>();
+    }
+};
 
 #endif // BORNAGAIN_GUI_MODEL_SAMPLE_ROUGHNESSMODELITEMS_H
diff --git a/GUI/Model/ToCore/SampleToCore.cpp b/GUI/Model/ToCore/SampleToCore.cpp
index b0c080881f275dc877ce5ea24ce70e8076c80d1c..c55cade30dce2da72bf7dbf2d75b40f16093d12e 100644
--- a/GUI/Model/ToCore/SampleToCore.cpp
+++ b/GUI/Model/ToCore/SampleToCore.cpp
@@ -121,7 +121,7 @@ std::unique_ptr<MultiLayer> GUI::ToCore::itemToSample(const SampleItem& sampleIt
                      layerItem->roughnessSelection().certainItem())) {
             LayerRoughness roughness(t->sigma().dVal(), t->hurst().dVal(),
                                      t->lateralCorrelationLength().dVal(),
-                                     t->certainRoughnessModel());
+                                     t->certainRoughnessModel()->createModel().release());
             sample->addLayerWithTopRoughness(*layer, roughness);
         } else
             sample->addLayer(*layer);
diff --git a/GUI/View/Realspace/RealspaceBuilder.cpp b/GUI/View/Realspace/RealspaceBuilder.cpp
index 25eda5e727f930cc4725f522d6bed4b71a2f2dbd..995bae13efd0d0674c292622386424d45129407f 100644
--- a/GUI/View/Realspace/RealspaceBuilder.cpp
+++ b/GUI/View/Realspace/RealspaceBuilder.cpp
@@ -96,9 +96,9 @@ std::unique_ptr<const double2d_t> layerRoughnessMap(const LayerItem& layerItem,
     std::unique_ptr<const double2d_t> result;
 
     if (const auto* br = dynamic_cast<const BasicRoughnessItem*>(layerItem.certainRoughness())) {
-        auto roughness =
-            LayerRoughness(br->sigma().dVal(), br->hurst().dVal(),
-                           br->lateralCorrelationLength().dVal(), br->certainRoughnessModel());
+        auto roughness = LayerRoughness(br->sigma().dVal(), br->hurst().dVal(),
+                                        br->lateralCorrelationLength().dVal(),
+                                        br->certainRoughnessModel()->createModel().release());
         int n = sceneGeometry.numRoughnessPointsAlongAxis;
         double L = 2 * sceneGeometry.layerSize;
         auto rmap = RoughnessMap(n, n, L, L, &roughness, seed); // seed < 0 ==> random every time
diff --git a/GUI/View/Sample/PolyForm.cpp b/GUI/View/Sample/PolyForm.cpp
index 7d68a1d8ac0cc413e2a631cfb4aeba3b5b22105f..1ec46bab2e5eee652315d185519a5548ef03d717 100644
--- a/GUI/View/Sample/PolyForm.cpp
+++ b/GUI/View/Sample/PolyForm.cpp
@@ -53,7 +53,7 @@ DoubleProperties PolyForm::doublePropertiesOfItem(FormfactorItem* item)
     return item->geometryProperties();
 }
 
-DoubleProperties PolyForm::doublePropertiesOfItem(RoughnessModel*)
+DoubleProperties PolyForm::doublePropertiesOfItem(RoughnessModelItem*)
 {
     return {};
 }
diff --git a/GUI/View/Sample/PolyForm.h b/GUI/View/Sample/PolyForm.h
index a8cfeb504354babfa876af2f25ef3dff28d9e2da..311748358726d50bfb25af3a6b7419ce5935b858 100644
--- a/GUI/View/Sample/PolyForm.h
+++ b/GUI/View/Sample/PolyForm.h
@@ -52,7 +52,7 @@ public:
     virtual void createContent();
 
 private:
-    static DoubleProperties doublePropertiesOfItem(class RoughnessModel* item);
+    static DoubleProperties doublePropertiesOfItem(class RoughnessModelItem* item);
     static DoubleProperties doublePropertiesOfItem(class FormfactorItem* item);
     static DoubleProperties doublePropertiesOfItem(class Profile1DItem* item);
     static DoubleProperties doublePropertiesOfItem(class Profile2DItem* item);