diff --git a/GUI/Model/Descriptor/DoubleProperty.cpp b/GUI/Model/Descriptor/DoubleProperty.cpp
index 61308be399b295d61786962785c4723a6970245d..a50af0d83897e079c48ea2991c7bb5ad294c4674 100644
--- a/GUI/Model/Descriptor/DoubleProperty.cpp
+++ b/GUI/Model/Descriptor/DoubleProperty.cpp
@@ -20,23 +20,39 @@
 using std::variant;
 
 void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
-                          const variant<QString, Unit>& unit, const QString& persistentTag)
+                          const variant<QString, Unit>& unit, const QString& uidPrefix)
 {
-    init(label, tooltip, value, unit, 3, RealLimits::nonnegative(), persistentTag);
+    init(label, tooltip, value, unit, 3 /*decimals*/, RealLimits::nonnegative(), uidPrefix);
 }
 
 void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
-                          const variant<QString, Unit>& unit, int decimals,
-                          const RealLimits& limits, const QString& persistentTag)
+                          const variant<QString, Unit>& unit, uint decimals,
+                          const RealLimits& limits, const QString& uidPrefix)
 {
+    init(label, tooltip, value, unit, decimals, 0.01 /*step*/, limits, uidPrefix);
+}
+
+void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
+                          const std::variant<QString, Unit>& unit, uint decimals, double step,
+                          const RealLimits& limits, const QString& uidPrefix)
+{
+    m_label = label;
+    m_tooltip = tooltip;
     m_value = value;
+    m_unit = unit;
     m_decimals = decimals;
-    m_persistentTag = persistentTag;
-    m_uid = QUuid::createUuid().toString(QUuid::WithoutBraces);
+    m_step = step;
+    m_limits = limits;
+
+    if (uidPrefix.size() > 0)
+        m_uid = uidPrefix + "/" + QUuid::createUuid().toString();
+    else
+        m_uid = QUuid::createUuid().toString();
 
+    // temporary
     m_descriptor.label = label;
     m_descriptor.tooltip = tooltip;
-    m_descriptor.decimals = m_decimals;
+    m_descriptor.decimals = decimals;
     m_descriptor.limits = limits;
     m_descriptor.unit = unit;
     m_descriptor.set = [=](double v) { m_value = v; };
@@ -46,16 +62,19 @@ void DoubleProperty::init(const QString& label, const QString& tooltip, double v
 
 void DoubleProperty::setTooltip(const QString& tooltip)
 {
+    m_tooltip = tooltip;
     m_descriptor.tooltip = tooltip;
 }
 
 void DoubleProperty::setUnit(const variant<QString, Unit>& unit)
 {
+    m_unit = unit;
     m_descriptor.unit = unit;
 }
 
 void DoubleProperty::setLimits(const RealLimits& limits)
 {
+    m_limits = limits;
     m_descriptor.limits = limits;
 }
 
@@ -70,14 +89,12 @@ void Serialize::rwProperty(Streamer& s, const QString& tag, DoubleProperty& d)
         w->writeStartElement(tag);
         GUI::Session::XML::writeAttribute(w, XML::Tags::Value, d.get());
         w->writeAttribute(XML::Tags::Id, d.uid());
-        GUI::Session::XML::writeAttribute(w, XML::Tags::Decimals, d.decimals());
         w->writeEndElement();
     } else if (QXmlStreamReader* r = s.xmlReader()) {
         r->readNextStartElement();
         s.assertCurrentTag(tag);
         d.set(r->attributes().value(XML::Tags::Value).toDouble());
         d.setUid(r->attributes().value(XML::Tags::Id).toString());
-        d.setDecimals(r->attributes().value(XML::Tags::Decimals).toUInt());
         s.gotoEndElementOfTag(tag);
     } else
         ASSERT(0);
diff --git a/GUI/Model/Descriptor/DoubleProperty.h b/GUI/Model/Descriptor/DoubleProperty.h
index 6aab1e51139331154f2b9d8c7ddbc2a2e3eb4481..16a1bfa3d1bb59948d1ecb672f870dc70bbdc26f 100644
--- a/GUI/Model/Descriptor/DoubleProperty.h
+++ b/GUI/Model/Descriptor/DoubleProperty.h
@@ -44,10 +44,13 @@ class Streamer;
 class DoubleProperty {
 public:
     void init(const QString& label, const QString& tooltip, double value,
-              const std::variant<QString, Unit>& unit, const QString& persistentTag);
+              const std::variant<QString, Unit>& unit, const QString& uidPrefix);
     void init(const QString& label, const QString& tooltip, double value,
-              const std::variant<QString, Unit>& unit, int decimals, const RealLimits& limits,
-              const QString& persistentTag);
+              const std::variant<QString, Unit>& unit, uint decimals, const RealLimits& limits,
+              const QString& uidPrefix);
+    void init(const QString& label, const QString& tooltip, double value,
+              const std::variant<QString, Unit>& unit, uint decimals, double step,
+              const RealLimits& limits, const QString& uidPrefix);
 
     //! Return a descriptor (information provider) for this double property.
     DoubleDescriptor descriptor() const { return m_descriptor; }
@@ -58,44 +61,45 @@ public:
     //! Cast to the contained double value.
     operator double() const { return m_value; }
 
-    //! Set the contained value.
-    void set(double d) { m_value = d; }
-
-    //! The contained value.
     double get() const { return m_value; }
+    void set(double d) { m_value = d; }
 
-    //! Persistent tag for serializing.
-    //    QString persistentTag() const { return m_persistentTag; }
-
-    //! Unique id of this double property.
     QString uid() const { return m_uid; }
-
-    //! Set the unique id of this double property.
     void setUid(const QString& uid) { m_uid = uid; }
 
-    //! Number of decimals to be shown in an edit field.
-    unsigned decimals() const { return m_decimals; }
+    double step() const { return m_step; }
+
+    QString label() const { return m_label; }
 
-    //! Set number of decimals to be shown in an edit field.
-    void setDecimals(unsigned decimals) { m_decimals = decimals; }
+    uint decimals() { return m_decimals; }
+    void setDecimals(uint decimals) { m_decimals = decimals; }
 
-    //! Set the tooltip
+    QString tooltip() const { return m_tooltip; }
     void setTooltip(const QString& tooltip);
 
-    //! Set the unit
+    std::variant<QString, Unit> unit() const { return m_unit; }
     void setUnit(const std::variant<QString, Unit>& unit);
 
-    //! Set the limits
+    RealLimits limits() { return m_limits; }
     void setLimits(const RealLimits& limits);
 
     //! True if one of the init methods has been called (checks for a valid uid).
     bool isInitialized() const;
 
 private:
-    double m_value = 0.0;          //!< Current value
-    unsigned m_decimals = 3;       //!< Number of decimals to be shown in an edit field
-    QString m_persistentTag;       //!< Persistent tag for serializing
-    QString m_uid;                 //!< Unique id of this double property.
+    double m_value = 0.0; //!< Current value
+    QString m_uid;        //!< Unique id of this double property.
+
+    // without serialization
+    QString m_label;      //!< A label text (short, no trailing colon)
+    QString m_tooltip;    //!< Tooltip text
+    uint m_decimals = 3;  //!< numbers of decimals to be shown in an edit control
+    double m_step = 0.01; //!< numbers of decimals to be shown in an edit control
+    RealLimits m_limits;  //!< Limits of the value.
+    std::variant<QString, Unit> m_unit =
+        Unit::unitless; //!< Unit of the value (internal unit only!)
+
+    // temporary
     DoubleDescriptor m_descriptor; //!< descriptor, holding more attributes like label, tooltip etc.
 };
 
diff --git a/GUI/Model/Descriptor/VectorDescriptor.h b/GUI/Model/Descriptor/VectorDescriptor.h
deleted file mode 100644
index f2a2930577fec8daf2ad1ff1517782948816f861..0000000000000000000000000000000000000000
--- a/GUI/Model/Descriptor/VectorDescriptor.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Descriptor/VectorDescriptor.h
-//! @brief     Defines class VectorDescriptor
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2021
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_VECTORDESCRIPTOR_H
-#define BORNAGAIN_GUI_MODEL_DESCRIPTOR_VECTORDESCRIPTOR_H
-
-
-#include "GUI/Model/Descriptor/DoubleDescriptor.h"
-#include <heinz/Vectors3D.h>
-
-//! Describes properties of a 3D vector, consisting of three double values.
-//!
-//! By using this class, the underlying data scheme is hidden from the user of the data. This e.g.
-//! eases SessionItem migration. The underlying implementation can be a R3 vector, a member array
-//! of three doubles, three double members, or any other construction to hold the three values.
-//!
-//! \a VectorProperty
-//! \a DoubleDescriptor
-//!
-class VectorDescriptor {
-public:
-    VectorDescriptor() = default;
-
-    VectorDescriptor(const QString& label, const QString& tooltip, double* xVar, double* yVar,
-                     double* zVar, const std::variant<QString, Unit>& unit)
-        : label(label)
-        , tooltip(tooltip)
-        , x("X", xVar, unit)
-        , y("Y", yVar, unit)
-        , z("Z", zVar, unit)
-    {
-        x.limits = RealLimits::limitless();
-        y.limits = RealLimits::limitless();
-        z.limits = RealLimits::limitless();
-        x.decimals = 3;
-        y.decimals = 3;
-        z.decimals = 3;
-        x.tooltip = tooltip;
-        y.tooltip = tooltip;
-        z.tooltip = tooltip;
-    }
-
-    VectorDescriptor(const QString& label, const QString& tooltip,
-                     const std::variant<QString, Unit>& unit)
-        : label(label)
-        , tooltip(tooltip)
-    {
-        x.limits = RealLimits::limitless();
-        y.limits = RealLimits::limitless();
-        z.limits = RealLimits::limitless();
-        x.decimals = 3;
-        y.decimals = 3;
-        z.decimals = 3;
-        x.tooltip = tooltip;
-        y.tooltip = tooltip;
-        z.tooltip = tooltip;
-        x.unit = unit;
-        y.unit = unit;
-        z.unit = unit;
-        x.label = "x";
-        y.label = "y";
-        z.label = "z";
-    }
-
-    void init(const QString& _label, const QString& _tooltip, const R3* vec,
-              const std::variant<QString, Unit>& _unit)
-    {
-        label = _label;
-        tooltip = _tooltip;
-        x.limits = RealLimits::limitless();
-        y.limits = RealLimits::limitless();
-        z.limits = RealLimits::limitless();
-        x.decimals = 3;
-        y.decimals = 3;
-        z.decimals = 3;
-        x.tooltip = tooltip;
-        y.tooltip = tooltip;
-        z.tooltip = tooltip;
-        x.unit = _unit;
-        y.unit = _unit;
-        z.unit = _unit;
-        x.label = "x";
-        y.label = "y";
-        z.label = "z";
-        x.set = [=](double v) { const_cast<R3*>(vec)->setX(v); };
-        x.get = [=]() { return vec->x(); };
-        x.path = [=] { return uid() + "x"; };
-        y.set = [=](double v) { const_cast<R3*>(vec)->setY(v); };
-        y.get = [=]() { return vec->y(); };
-        y.path = [=] { return uid() + "y"; };
-        z.set = [=](double v) { const_cast<R3*>(vec)->setZ(v); };
-        z.get = [=]() { return vec->z(); };
-        z.path = [=] { return uid() + "z"; };
-    }
-
-
-    QString label;   //!< A label text (short, no trailing colon)
-    QString tooltip; //!< Tooltip text
-    DoubleDescriptor x;
-    DoubleDescriptor y;
-    DoubleDescriptor z;
-    std::function<QString()> uid; //!< unique id describing  this value. Used e.g. for undo/redo
-};
-
-#endif // BORNAGAIN_GUI_MODEL_DESCRIPTOR_VECTORDESCRIPTOR_H
diff --git a/GUI/Model/Descriptor/VectorProperty.cpp b/GUI/Model/Descriptor/VectorProperty.cpp
index 02265a3dd89363d76ce3222d6f8f6904b8c01185..e823a19d6115427f2b9aaf7a2e9b5a6a45aaf173 100644
--- a/GUI/Model/Descriptor/VectorProperty.cpp
+++ b/GUI/Model/Descriptor/VectorProperty.cpp
@@ -17,42 +17,65 @@
 #include "GUI/Support/XML/UtilXML.h"
 #include <QUuid>
 
+namespace {
+namespace Tag {
+
+const QString X("X");
+const QString Y("Y");
+const QString Z("Z");
+
+} // namespace Tag
+} // namespace
+
 using std::variant;
 
 void VectorProperty::init(const QString& label, const QString& tooltip,
-                          const variant<QString, Unit>& unit, const QString& persistentTag)
+                          const variant<QString, Unit>& unit, const QString& uidPrefix)
 {
-    m_persistentTag = persistentTag;
-    m_uid = QUuid::createUuid().toString();
+    init(label, tooltip, R3(0.0, 0.0, 0.0), unit, 3 /*decimals*/, 0.01 /*step*/,
+         RealLimits::limitless(), uidPrefix);
+}
 
-    m_descriptor.init(label, tooltip, &m_value, unit);
-    m_descriptor.uid = [this] { return m_uid; };
+void VectorProperty::init(const QString& label, const QString& tooltip, const R3& value,
+                          const std::variant<QString, Unit>& unit, uint decimals, double step,
+                          const RealLimits& limits, const QString& uidPrefix)
+{
+    m_label = label;
+
+    m_x.init("x", tooltip, value.x(), unit, decimals, step, limits, uidPrefix);
+    m_y.init("y", tooltip, value.y(), unit, decimals, step, limits, uidPrefix);
+    m_z.init("z", tooltip, value.z(), unit, decimals, step, limits, uidPrefix);
+
+    if (uidPrefix.size() > 0)
+        m_uid = uidPrefix + "/" + QUuid::createUuid().toString();
+    else
+        m_uid = QUuid::createUuid().toString();
+
+    m_x.setUid(m_uid + "/x");
+    m_y.setUid(m_uid + "/y");
+    m_z.setUid(m_uid + "/z");
 }
 
 bool VectorProperty::operator==(const VectorProperty& other) const
 {
-    return (m_value == other.m_value) && (m_uid == other.m_uid)
-           && (m_persistentTag == other.m_persistentTag);
+    return (r3() == other.r3()) && (m_uid == other.m_uid) && (m_label == other.m_label);
 }
 
-
-void Serialize::rwProperty(Streamer& s, VectorProperty& d)
+void VectorProperty::rwProperty(Streamer& s, const QString& tag)
 {
     if (QXmlStreamWriter* w = s.xmlWriter()) {
-        w->writeStartElement(d.persistentTag());
-        GUI::Session::XML::writeAttribute(w, XML::Tags::Value, d.get());
-        GUI::Session::XML::writeUid(w, d.uid());
+        w->writeStartElement(tag);
+        Serialize::rwProperty(s, Tag::X, m_x);
+        Serialize::rwProperty(s, Tag::Y, m_y);
+        Serialize::rwProperty(s, Tag::Z, m_z);
         w->writeEndElement();
     } else if (QXmlStreamReader* r = s.xmlReader()) {
         r->readNextStartElement();
-        s.assertCurrentTag(d.persistentTag());
-        R3 vec;
-        QString uid;
-        GUI::Session::XML::readAttribute(r, XML::Tags::Value, &vec);
-        GUI::Session::XML::readAttribute(r, XML::Tags::Id, &uid);
-        d.set(vec);
-        d.setUid(uid);
-        s.gotoEndElementOfTag(d.persistentTag());
+        s.assertCurrentTag(tag);
+        Serialize::rwProperty(s, Tag::X, m_x);
+        Serialize::rwProperty(s, Tag::Y, m_y);
+        Serialize::rwProperty(s, Tag::Z, m_z);
+        s.gotoEndElementOfTag(tag);
     } else
         ASSERT(0);
 }
diff --git a/GUI/Model/Descriptor/VectorProperty.h b/GUI/Model/Descriptor/VectorProperty.h
index a0bf9016212800e13ce3c9f845084513a1906752..ddae4b145fc42cdad72ea59574b875e00cf877b3 100644
--- a/GUI/Model/Descriptor/VectorProperty.h
+++ b/GUI/Model/Descriptor/VectorProperty.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_VECTORPROPERTY_H
 #define BORNAGAIN_GUI_MODEL_DESCRIPTOR_VECTORPROPERTY_H
 
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
+#include "GUI/Model/Descriptor/DoubleProperty.h"
 #include <heinz/Vectors3D.h>
 
 class Streamer;
@@ -27,40 +27,49 @@ class Streamer;
 //!
 //! For a more complete documentation about property classes, please refer to DoubleProperty.
 //!
-//! \sa VectorDescriptor
 //! \sa DoubleProperty
 //!
 class VectorProperty {
 public:
     void init(const QString& label, const QString& tooltip, const std::variant<QString, Unit>& unit,
-              const QString& persistentTag);
+              const QString& uidPrefix);
+    void init(const QString& label, const QString& tooltip, const R3& value,
+              const std::variant<QString, Unit>& unit, uint decimals, double step,
+              const RealLimits& limits, const QString& uidPrefix);
 
-    VectorDescriptor descriptor() const { return m_descriptor; }
-    operator VectorDescriptor() const { return m_descriptor; }
-    operator R3() const { return m_value; }
+    operator R3() const { return R3(m_x.get(), m_y.get(), m_z.get()); }
     bool operator==(const VectorProperty& other) const;
 
-    void set(const R3& d) { m_value = d; }
-    R3 get() const { return m_value; }
+    void setX(double _x) { m_x.set(_x); }
+    void setY(double _y) { m_y.set(_y); }
+    void setZ(double _z) { m_z.set(_z); }
+    void set(const R3& d)
+    {
+        setX(d.x());
+        setY(d.y());
+        setZ(d.z());
+    }
+    R3 r3() const { return *this; }
 
-    QString persistentTag() const { return m_persistentTag; }
     QString uid() const { return m_uid; }
-    void setUid(const QString& uid) { m_uid = uid; }
 
-    R3& r3() { return m_value; }
+    QString label() const { return m_label; }
+
+    void rwProperty(Streamer& s, const QString& tag);
+
+    DoubleDescriptor x() const { return m_x; }
+    DoubleDescriptor y() const { return m_y; }
+    DoubleDescriptor z() const { return m_z; }
 
 private:
-    R3 m_value;
-    QString m_persistentTag;
-    QString m_uid;
+    QString m_uid; //!< Unique id of this vector property.
+    QString m_label;
 
-    VectorDescriptor m_descriptor;
+    DoubleProperty m_x;
+    DoubleProperty m_y;
+    DoubleProperty m_z;
 };
 
-namespace Serialize {
-void rwProperty(Streamer& s, VectorProperty& d);
-} // namespace Serialize
-
 // clang-format off
 
 //! Add a member, a getter and a setter for a VectorProperty
@@ -68,7 +77,7 @@ void rwProperty(Streamer& s, VectorProperty& d);
 protected:                                                       \
     VectorProperty m_##nameLower;                                \
 public:                                                          \
-    VectorDescriptor nameLower() const { return m_##nameLower; } \
+    const VectorProperty& nameLower() const { return m_##nameLower; }   \
     void set##nameUpper(const R3& v) { m_##nameLower.set(v); }
 
 // clang-format on
diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp
index 49ee4bcf2d43c916b9b29c375cd1e86fabc76633..6dea79c3835bbffa8ed465b7f91a21946c1147e4 100644
--- a/GUI/Model/Device/InstrumentItems.cpp
+++ b/GUI/Model/Device/InstrumentItems.cpp
@@ -51,6 +51,8 @@ const QString WithPolarizerAnalyzer("WithPolarizerAnalyzer");
 const QString AnalyzerEfficiency("AnalyzerEfficiency");
 const QString AnalyzerTotalTransmission("AnalyzerTotalTransmission");
 const QString Beam("Beam");
+const QString Polarization("Polarization");
+const QString AnalyzerDirection("AnalyzerDirection");
 
 } // namespace Tag
 
@@ -166,8 +168,8 @@ void InstrumentItem::serialize(Streamer& s)
     Serialize::rwValue(s, Tag::Name, m_name);
     Serialize::rwValue(s, Tag::Description, m_description);
     Serialize::rwValue(s, Tag::WithPolarizerAnalyzer, m_withPolarizerAnalyzer);
-    Serialize::rwProperty(s, m_polarization);
-    Serialize::rwProperty(s, m_analyzerDirection);
+    m_polarization.rwProperty(s, Tag::Polarization);
+    m_analyzerDirection.rwProperty(s, Tag::AnalyzerDirection);
     Serialize::rwProperty(s, Tag::AnalyzerEfficiency, m_analyzerEfficiency);
     Serialize::rwProperty(s, Tag::AnalyzerTotalTransmission, m_analyzerTotalTransmission);
     Serialize::rwSelected<BackgroundItemCatalog>(s, m_backgroundItem);
diff --git a/GUI/Model/Device/RectangularDetectorItem.cpp b/GUI/Model/Device/RectangularDetectorItem.cpp
index 12fbfcc2baf5bf63d1558831e73f97885cece430..c60589abe22ce1e71938396eae4db42dbb27241b 100644
--- a/GUI/Model/Device/RectangularDetectorItem.cpp
+++ b/GUI/Model/Device/RectangularDetectorItem.cpp
@@ -35,6 +35,8 @@ const QString Height("Height");
 const QString u0("u0");
 const QString v0("v0");
 const QString Distance("Distance");
+const QString NormalVector("NormalVector");
+const QString DirectionVector("DirectionVector");
 
 } // namespace Tag
 
@@ -93,11 +95,11 @@ RectangularDetectorItem::RectangularDetectorItem()
         "Normal vector",
         "Normal of the detector plane with length equal to the sample detector distance",
         Unit::unitless, "normalVector");
-    m_normalVector.r3().setX(default_detector_distance);
+    m_normalVector.setX(default_detector_distance);
     m_directionVector.init("Direction vector",
                            "Detector axis direction vector w.r.t. the sample coordinate system",
                            Unit::unitless, "directionVector");
-    m_directionVector.r3().setY(-1.0);
+    m_directionVector.setY(-1.0);
 
     m_u0.init("u0", "", default_detector_width / 2., "mm", 3, RealLimits::limitless(), "u0");
     m_v0.init("v0", "", 0.0, "mm", 3, RealLimits::limitless(), "v0");
@@ -124,8 +126,8 @@ void RectangularDetectorItem::serialize(Streamer& s)
     Serialize::rwProperty(s, Tag::Width, m_width);
     Serialize::rwProperty(s, Tag::Height, m_height);
     Serialize::rwValue(s, Tag::Alignment, alignment);
-    Serialize::rwProperty(s, m_normalVector);
-    Serialize::rwProperty(s, m_directionVector);
+    m_normalVector.rwProperty(s, Tag::NormalVector);
+    m_directionVector.rwProperty(s, Tag::DirectionVector);
     Serialize::rwProperty(s, Tag::u0, m_u0);
     Serialize::rwProperty(s, Tag::v0, m_v0);
     Serialize::rwProperty(s, Tag::Distance, m_distance);
@@ -185,7 +187,7 @@ RectangularDetectorItem::detectorAlignmentSelection() const
     return d;
 }
 
-QVector<std::variant<VectorDescriptor, DoubleDescriptor>>
+QVector<std::variant<VectorProperty, DoubleDescriptor>>
 RectangularDetectorItem::alignmentPropertiesForUI() const
 {
     if (m_detectorAlignment == RectangularDetector::GENERIC)
diff --git a/GUI/Model/Device/RectangularDetectorItem.h b/GUI/Model/Device/RectangularDetectorItem.h
index 57b19ba5713c18b7a470f5d0ff99d23fddebf684..90fe7f0af4bea9777d82b25e6f47175d9c0b2fe0 100644
--- a/GUI/Model/Device/RectangularDetectorItem.h
+++ b/GUI/Model/Device/RectangularDetectorItem.h
@@ -52,7 +52,7 @@ public:
     detectorAlignmentSelection() const;
 
     //! The properties of the currently active alignment. Sorted as expected on the UI
-    QVector<std::variant<VectorDescriptor, DoubleDescriptor>> alignmentPropertiesForUI() const;
+    QVector<std::variant<VectorProperty, DoubleDescriptor>> alignmentPropertiesForUI() const;
 
     VECTOR_PROPERTY(normalVector, NormalVector);
     VECTOR_PROPERTY(directionVector, DirectionVector);
diff --git a/GUI/Model/Job/ParameterTreeItems.cpp b/GUI/Model/Job/ParameterTreeItems.cpp
index 7aaa9be49def6ee99f81d279ee37bbc22252785b..50a29e6393603ca4cacd209f5f80326ca40f343e 100644
--- a/GUI/Model/Job/ParameterTreeItems.cpp
+++ b/GUI/Model/Job/ParameterTreeItems.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Job/ParameterTreeItems.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Job/JobItem.h"
 #include "GUI/Model/Sample/MaterialItem.h"
 #include "GUI/Model/Sample/MaterialItems.h"
diff --git a/GUI/Model/Model/ParameterTreeUtils.cpp b/GUI/Model/Model/ParameterTreeUtils.cpp
index 09a01b4de4537ea73d91560c0d53516a515cf26a..9a0845a700a92a002f0dd13f5f388fb6eb4161c5 100644
--- a/GUI/Model/Model/ParameterTreeUtils.cpp
+++ b/GUI/Model/Model/ParameterTreeUtils.cpp
@@ -150,16 +150,16 @@ void ParameterTreeBuilder::addParameterItem(ParameterLabelItem* parent, const Do
         m_jobItem->parameterContainerItem()->setBackupValue(parameterItem->link(), d.get());
 }
 
-void ParameterTreeBuilder::addParameterItem(ParameterLabelItem* parent, const VectorDescriptor& d)
+void ParameterTreeBuilder::addParameterItem(ParameterLabelItem* parent, const VectorProperty& d)
 {
-    auto* label = new ParameterLabelItem(d.label, parent);
-    addParameterItem(label, d.x);
-    addParameterItem(label, d.y);
-    addParameterItem(label, d.z);
+    auto* label = new ParameterLabelItem(d.label(), parent);
+    addParameterItem(label, d.x());
+    addParameterItem(label, d.y());
+    addParameterItem(label, d.z());
 }
 
-void ParameterTreeBuilder::addParameterItem(
-    ParameterLabelItem* parent, const std::variant<VectorDescriptor, DoubleDescriptor>& v)
+void ParameterTreeBuilder::addParameterItem(ParameterLabelItem* parent,
+                                            const std::variant<VectorProperty, DoubleDescriptor>& v)
 {
     std::visit([=](auto const& e) { addParameterItem(parent, e); }, v);
 }
diff --git a/GUI/Model/Model/ParameterTreeUtils.h b/GUI/Model/Model/ParameterTreeUtils.h
index e64465218fd28fe3114f5cf112c44f2e51f5b8c6..737747dc621b90e22853f45101275ab8744681ee 100644
--- a/GUI/Model/Model/ParameterTreeUtils.h
+++ b/GUI/Model/Model/ParameterTreeUtils.h
@@ -25,7 +25,7 @@ class ParameterItem;
 class ParameterLabelItem;
 class ParameterContainerItem;
 class DoubleDescriptor;
-class VectorDescriptor;
+class VectorProperty;
 class ParticleLayoutItem;
 class ItemWithParticles;
 class Interference2DAbstractLatticeItem;
@@ -54,9 +54,9 @@ private:
     void addInstrument();
     void addParameterItem(ParameterLabelItem* parent, const DoubleDescriptor& d,
                           const QString& label = QString());
-    void addParameterItem(ParameterLabelItem* parent, const VectorDescriptor& d);
+    void addParameterItem(ParameterLabelItem* parent, const VectorProperty& d);
     void addParameterItem(ParameterLabelItem* parent,
-                          const std::variant<VectorDescriptor, DoubleDescriptor>& v);
+                          const std::variant<VectorProperty, DoubleDescriptor>& v);
     ParameterContainerItem* parameterContainer();
     bool allowMagneticFields() const;
 
diff --git a/GUI/Model/Sample/CompoundItem.cpp b/GUI/Model/Sample/CompoundItem.cpp
index 6ff879aad9735e8ad3bebfddcd122f0a5adc772b..de853876023d0ec224d28333be39d4f367ec60b8 100644
--- a/GUI/Model/Sample/CompoundItem.cpp
+++ b/GUI/Model/Sample/CompoundItem.cpp
@@ -29,6 +29,7 @@ namespace {
 namespace Tag {
 
 const QString Abundance("Abundance");
+const QString Position("Position");
 const QString Particles("Particles");
 
 } // namespace Tag
@@ -53,7 +54,7 @@ void CompoundItem::serialize(Streamer& s)
 {
     s.assertVersion(0);
     Serialize::rwProperty(s, Tag::Abundance, m_abundance);
-    Serialize::rwProperty(s, m_position);
+    m_position.rwProperty(s, Tag::Position);
     Serialize::rwSelected<RotationItemCatalog>(s, m_rotation);
     Serialize::rwCatalogized<ItemWithParticlesCatalog>(s, Tag::Particles, m_particles, m_materials);
 }
diff --git a/GUI/Model/Sample/CoreAndShellItem.cpp b/GUI/Model/Sample/CoreAndShellItem.cpp
index e6d038044d2f5d6b792cdaa81444e24a02024661..051e25ed7dc7768241c8acf59dba44a14efda61f 100644
--- a/GUI/Model/Sample/CoreAndShellItem.cpp
+++ b/GUI/Model/Sample/CoreAndShellItem.cpp
@@ -27,6 +27,7 @@ namespace {
 namespace Tag {
 
 const QString Abundance("Abundance");
+const QString Position("Position");
 const QString Core("Core");
 const QString Shell("Shell");
 
@@ -50,7 +51,7 @@ void CoreAndShellItem::serialize(Streamer& s)
 {
     s.assertVersion(0);
     Serialize::rwProperty(s, Tag::Abundance, m_abundance);
-    Serialize::rwProperty(s, m_position);
+    m_position.rwProperty(s, Tag::Position);
     Serialize::rwOptional(s, Tag::Core, m_core, m_materials);
     Serialize::rwOptional(s, Tag::Shell, m_shell, m_materials);
 }
diff --git a/GUI/Model/Sample/InterferenceItems.cpp b/GUI/Model/Sample/InterferenceItems.cpp
index a8ed565c14b811213bf20f174873b6b63fc92915..a71c1416a0d5c54e5f9fc18dd1df18c815023508 100644
--- a/GUI/Model/Sample/InterferenceItems.cpp
+++ b/GUI/Model/Sample/InterferenceItems.cpp
@@ -307,7 +307,8 @@ InterferenceHardDiskItem::InterferenceHardDiskItem()
 {
     m_radius.init("Radius", "Hard disk radius", 5.0, Unit::nanometer, "radius");
     m_density.init("Total particle density", "Particle density in particles per area", 0.002,
-                   Unit::nanometerMinus2, "density");
+                   Unit::nanometerMinus2, 5 /* decimals */, 0.0001 /* step */,
+                   RealLimits::nonnegative(), "density");
 }
 
 std::unique_ptr<IInterference> InterferenceHardDiskItem::createInterference() const
diff --git a/GUI/Model/Sample/ItemWithParticles.cpp b/GUI/Model/Sample/ItemWithParticles.cpp
index a6c1ab67f0294fcc14c09d9feed926ac4a5062ef..8b1da0bab79a46da5e74b781519f48263fc5e661 100644
--- a/GUI/Model/Sample/ItemWithParticles.cpp
+++ b/GUI/Model/Sample/ItemWithParticles.cpp
@@ -49,7 +49,7 @@ void ItemWithParticles::setPosition(const R3& position)
     m_position.set(position);
 }
 
-VectorDescriptor ItemWithParticles::positionVector() const
+const VectorProperty& ItemWithParticles::positionVector() const
 {
     return m_position;
 }
diff --git a/GUI/Model/Sample/ItemWithParticles.h b/GUI/Model/Sample/ItemWithParticles.h
index 329a726ba2041ae004aa574b05d589482ae4b9d4..390cd944668aba08ca588dba86bddc250ec05d7d 100644
--- a/GUI/Model/Sample/ItemWithParticles.h
+++ b/GUI/Model/Sample/ItemWithParticles.h
@@ -33,7 +33,7 @@ public:
 
     R3 position() const;
     void setPosition(const R3& position);
-    VectorDescriptor positionVector() const;
+    const VectorProperty& positionVector() const;
 
     //! Returns selection descriptor for rotation methods.
     SelectionDescriptor<RotationItem*> rotation();
diff --git a/GUI/Model/Sample/MaterialItem.cpp b/GUI/Model/Sample/MaterialItem.cpp
index 66647cd5898f27e051b348e449483e648c478478..80852cbe3f7e68da070e4519c79d5090ef761bd0 100644
--- a/GUI/Model/Sample/MaterialItem.cpp
+++ b/GUI/Model/Sample/MaterialItem.cpp
@@ -119,10 +119,6 @@ DoubleDescriptor MaterialItem::sldIm()
     return m_sldIm;
 }
 
-VectorDescriptor MaterialItem::magnetizationVector()
-{
-    return m_magnetization;
-}
 
 bool MaterialItem::hasRefractiveIndex() const
 {
@@ -172,7 +168,7 @@ R3 MaterialItem::magnetization() const
 
 void MaterialItem::setMagnetization(const R3& magnetization)
 {
-    if (m_magnetization.get() != magnetization) {
+    if (m_magnetization.r3() != magnetization) {
         m_magnetization.set(magnetization);
         emit dataChanged();
     }
@@ -194,7 +190,7 @@ void MaterialItem::serialize(Streamer& s)
     Serialize::rwValue(s, Tag::Name, m_name);
     Serialize::rwValue(s, Tag::Id, m_id);
     Serialize::rwValue(s, Tag::Color, m_color);
-    Serialize::rwProperty(s, /*Tag::Magnetization,*/ m_magnetization);
+    m_magnetization.rwProperty(s, Tag::Magnetization);
     Serialize::rwValue(s, Tag::UseRefractiveIndex, m_useRefractiveIndex);
 
     // read m_useRefractiveIndex before moving on
diff --git a/GUI/Model/Sample/MaterialItem.h b/GUI/Model/Sample/MaterialItem.h
index 050e63bc855abe84a81279d4fb74a9962aa478b5..093e43866499337164f2d2dfe4f452cd63321a0d 100644
--- a/GUI/Model/Sample/MaterialItem.h
+++ b/GUI/Model/Sample/MaterialItem.h
@@ -56,7 +56,7 @@ public:
     DoubleDescriptor beta();
     DoubleDescriptor sldRe();
     DoubleDescriptor sldIm();
-    VectorDescriptor magnetizationVector();
+    const VectorProperty& magnetizationVector() const { return m_magnetization; }
 
     /// \return true if refractive index was given, otherwise SLD was given
     bool hasRefractiveIndex() const;
diff --git a/GUI/Model/Sample/MesocrystalItem.cpp b/GUI/Model/Sample/MesocrystalItem.cpp
index a5bf7b609faff41b61777172b1d3920e809d4620..f8de23536ca2dce178d3b33b15013b355b2c590e 100644
--- a/GUI/Model/Sample/MesocrystalItem.cpp
+++ b/GUI/Model/Sample/MesocrystalItem.cpp
@@ -34,8 +34,12 @@ namespace {
 namespace Tag {
 
 const QString Abundance("Abundance");
+const QString Position("Position");
+const QString VectorA("VectorA");
+const QString VectorB("VectorB");
+const QString VectorC("VectorC");
 
-}
+} // namespace Tag
 
 const QString abundance_tooltip = "Proportion of this type of mesocrystal normalized to the \n"
                                   "total number of particles in the layout";
@@ -64,11 +68,11 @@ void MesocrystalItem::serialize(Streamer& s)
 {
     s.assertVersion(0);
     Serialize::rwProperty(s, Tag::Abundance, m_abundance);
-    Serialize::rwProperty(s, m_position);
+    m_position.rwProperty(s, Tag::Position);
     Serialize::rwSelected<RotationItemCatalog>(s, m_rotation);
-    Serialize::rwProperty(s, m_vectorA);
-    Serialize::rwProperty(s, m_vectorB);
-    Serialize::rwProperty(s, m_vectorC);
+    m_vectorA.rwProperty(s, Tag::VectorA);
+    m_vectorB.rwProperty(s, Tag::VectorB);
+    m_vectorC.rwProperty(s, Tag::VectorC);
     Serialize::rwSelected<FormFactorItemCatalog>(s, m_outerShape);
     Serialize::rwSelected<ItemWithParticlesCatalog>(s, m_basisParticle, m_materials);
 }
@@ -160,20 +164,6 @@ void MesocrystalItem::setRawDataVectorC(const R3& v)
     m_vectorC.set(v);
 }
 
-VectorDescriptor MesocrystalItem::vectorA() const
-{
-    return m_vectorA;
-}
-
-VectorDescriptor MesocrystalItem::vectorB() const
-{
-    return m_vectorB;
-}
-
-VectorDescriptor MesocrystalItem::vectorC() const
-{
-    return m_vectorC;
-}
 
 QVector<ItemWithParticles*> MesocrystalItem::containedItemsWithParticles() const
 {
diff --git a/GUI/Model/Sample/MesocrystalItem.h b/GUI/Model/Sample/MesocrystalItem.h
index a8e906e169265b95d4d88f06280905c670de8447..5deb298945c5b58fb0971e2c2c5327a615f4e565 100644
--- a/GUI/Model/Sample/MesocrystalItem.h
+++ b/GUI/Model/Sample/MesocrystalItem.h
@@ -51,9 +51,9 @@ public:
     void setRawDataVectorB(const R3& vector_b);
     void setRawDataVectorC(const R3& vector_c);
 
-    VectorDescriptor vectorA() const;
-    VectorDescriptor vectorB() const;
-    VectorDescriptor vectorC() const;
+    const VectorProperty& vectorA() const { return m_vectorA; }
+    const VectorProperty& vectorB() const { return m_vectorB; }
+    const VectorProperty& vectorC() const { return m_vectorC; }
 
     QVector<ItemWithParticles*> containedItemsWithParticles() const override;
 
diff --git a/GUI/Model/Sample/MultiLayerItem.cpp b/GUI/Model/Sample/MultiLayerItem.cpp
index d6a6bbc2c56ee013649fd61ad93c0dd832895cf2..428a82c1733a6fbf41d3b7ed795c13c8c2181789 100644
--- a/GUI/Model/Sample/MultiLayerItem.cpp
+++ b/GUI/Model/Sample/MultiLayerItem.cpp
@@ -26,6 +26,7 @@ const QString Description("Description");
 const QString CrossCorrelationLength("CrossCorrelationLength");
 const QString Materials("Materials");
 const QString Layers("Layers");
+const QString ExternalField("ExternalField");
 
 } // namespace Tag
 } // namespace
@@ -95,11 +96,6 @@ void MultiLayerItem::setExternalField(const R3& externalField)
     m_externalField.set(externalField);
 }
 
-VectorDescriptor MultiLayerItem::externalFieldVector() const
-{
-    return m_externalField;
-}
-
 QVector<LayerItem*> MultiLayerItem::layers() const
 {
     return m_layers;
@@ -159,7 +155,7 @@ void MultiLayerItem::serialize(Streamer& s)
     Serialize::rwValue(s, Tag::Name, m_name);
     Serialize::rwValue(s, Tag::Description, m_description);
     Serialize::rwProperty(s, Tag::CrossCorrelationLength, m_crossCorrelationLength);
-    Serialize::rwProperty(s, m_externalField);
+    m_externalField.rwProperty(s, Tag::ExternalField);
     Serialize::rwClass(s, Tag::Materials, m_materials);
     Serialize::rwVector(s, Tag::Layers, m_layers, &m_materials);
 
diff --git a/GUI/Model/Sample/MultiLayerItem.h b/GUI/Model/Sample/MultiLayerItem.h
index d7c9eb1f524a72b1bf96f7ad9ad2cb2e01a4b003..1287ed48b8e0a1b02503273d636ad03ca617e05c 100644
--- a/GUI/Model/Sample/MultiLayerItem.h
+++ b/GUI/Model/Sample/MultiLayerItem.h
@@ -49,7 +49,7 @@ public:
 
     R3 externalField() const;
     void setExternalField(const R3& externalField);
-    VectorDescriptor externalFieldVector() const;
+    const VectorProperty& externalFieldVector() const { return m_externalField; }
 
     QVector<LayerItem*> layers() const;
 
diff --git a/GUI/Model/Sample/ParticleItem.cpp b/GUI/Model/Sample/ParticleItem.cpp
index c65c08ce34f561672e47a89e3e29d169f1d2025b..c86565deaad621b6af2df7c76a78d20dc9a374c7 100644
--- a/GUI/Model/Sample/ParticleItem.cpp
+++ b/GUI/Model/Sample/ParticleItem.cpp
@@ -28,8 +28,9 @@ namespace {
 namespace Tag {
 
 const QString Abundance("Abundance");
+const QString Position("Position");
 
-}
+} // namespace Tag
 
 const QString abundance_tooltip = "Proportion of this type of particles normalized to the \n"
                                   "total number of particles in the layout";
@@ -52,7 +53,7 @@ void ParticleItem::serialize(Streamer& s)
     s.assertVersion(0);
     Serialize::rwValue(s, "MaterialIdentifier", m_materialIdentifier);
     Serialize::rwProperty(s, Tag::Abundance, m_abundance);
-    Serialize::rwProperty(s, m_position);
+    m_position.rwProperty(s, Tag::Position);
     Serialize::rwSelected<RotationItemCatalog>(s, m_rotation);
     Serialize::rwSelected<FormFactorItemCatalog>(s, m_formFactor);
 }
diff --git a/GUI/Model/Sample/ParticleLayoutItem.cpp b/GUI/Model/Sample/ParticleLayoutItem.cpp
index ee630d166e8d1f0295e937275497c886800fe89c..ed5afb0b2362e74d0747ed06870f988671499395 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.cpp
+++ b/GUI/Model/Sample/ParticleLayoutItem.cpp
@@ -37,7 +37,8 @@ ParticleLayoutItem::ParticleLayoutItem(const MaterialItems* materials)
     m_ownDensity.init("Total particle density",
                       "Number of particles per area (particle surface density).\n "
                       "Should be defined for disordered and 1d-ordered particle collections.",
-                      0.0005, Unit::nanometerMinus2, 10, RealLimits::nonnegative(), "density");
+                      0.0005, Unit::nanometerMinus2, 10 /* decimals */, 0.0001 /* step */,
+                      RealLimits::nonnegative(), "density");
 
     m_interference.init<InterferenceItemCatalog>("Interference function", "", "interference");
 }
diff --git a/GUI/View/Instrument/DetectorAlignmentEditor.cpp b/GUI/View/Instrument/DetectorAlignmentEditor.cpp
index b81fc7f5d86af521d302e65900c92d32f33c7dfc..0ec4aa1c9361acba5e7a0e7378e39f7353062194 100644
--- a/GUI/View/Instrument/DetectorAlignmentEditor.cpp
+++ b/GUI/View/Instrument/DetectorAlignmentEditor.cpp
@@ -86,7 +86,7 @@ DoubleSpinBox* DetectorAlignmentEditor::createSpinBox(const DoubleDescriptor& d)
     return sb;
 }
 
-void DetectorAlignmentEditor::addVector(QFormLayout* parentLayout, const VectorDescriptor& d)
+void DetectorAlignmentEditor::addVector(QFormLayout* parentLayout, const VectorProperty& d)
 {
     auto* layout = new QHBoxLayout;
 
@@ -95,13 +95,13 @@ void DetectorAlignmentEditor::addVector(QFormLayout* parentLayout, const VectorD
         layout->addWidget(createSpinBox(d));
     };
 
-    add(d.x);
-    add(d.y);
-    add(d.z);
+    add(d.x());
+    add(d.y());
+    add(d.z());
 
     layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
 
-    parentLayout->addRow(d.label + ":", layout);
+    parentLayout->addRow(d.label() + ":", layout);
 }
 
 void DetectorAlignmentEditor::createAligmentWidgets()
diff --git a/GUI/View/Instrument/DetectorAlignmentEditor.h b/GUI/View/Instrument/DetectorAlignmentEditor.h
index 749d5f2e021ab7c442528414643fda3577725bbe..37fde4527bee5be6d128c136bfacc03547b9f94d 100644
--- a/GUI/View/Instrument/DetectorAlignmentEditor.h
+++ b/GUI/View/Instrument/DetectorAlignmentEditor.h
@@ -22,7 +22,7 @@ class RectangularDetectorItem;
 class QFormLayout;
 class DoubleSpinBox;
 class DoubleDescriptor;
-class VectorDescriptor;
+class VectorProperty;
 
 /// Widget for selecting the alignment of a detector (combo box) and input of the corresponding
 /// values
@@ -39,7 +39,7 @@ private:
     void createAligmentWidgets();
     DoubleSpinBox* createSpinBox(QFormLayout* parentFormLayout, const DoubleDescriptor& d);
     DoubleSpinBox* createSpinBox(const DoubleDescriptor& d);
-    void addVector(QFormLayout* parentLayout, const VectorDescriptor& d);
+    void addVector(QFormLayout* parentLayout, const VectorProperty& d);
 
 private:
     RectangularDetectorItem* m_item;
diff --git a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp b/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
index 9345b0b1fb4a8cd70cc55fccb04058d8bf8d13cb..98682e9ccf71431fa983dcca3ba97e28a659f523 100644
--- a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
+++ b/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
@@ -68,7 +68,7 @@ DoubleSpinBox* PolarizationAnalysisEditor::createSpinBox(const DoubleDescriptor&
     return sb;
 }
 
-void PolarizationAnalysisEditor::addVector(QFormLayout* parentLayout, const VectorDescriptor& d)
+void PolarizationAnalysisEditor::addVector(QFormLayout* parentLayout, const VectorProperty& d)
 {
     auto* layout = new QHBoxLayout;
 
@@ -77,11 +77,11 @@ void PolarizationAnalysisEditor::addVector(QFormLayout* parentLayout, const Vect
         layout->addWidget(createSpinBox(d));
     };
 
-    add(d.x);
-    add(d.y);
-    add(d.z);
+    add(d.x());
+    add(d.y());
+    add(d.z());
 
     layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
 
-    parentLayout->addRow(d.label + ":", layout);
+    parentLayout->addRow(d.label() + ":", layout);
 }
diff --git a/GUI/View/Instrument/PolarizationAnalysisEditor.h b/GUI/View/Instrument/PolarizationAnalysisEditor.h
index e5b23c34db719cb446dfcca1d9454ef86f12938b..a32adb20e3a7165d0f13e2c66b622d1301e63c7f 100644
--- a/GUI/View/Instrument/PolarizationAnalysisEditor.h
+++ b/GUI/View/Instrument/PolarizationAnalysisEditor.h
@@ -21,7 +21,7 @@ class InstrumentItem;
 class DoubleSpinBox;
 class DoubleDescriptor;
 class QFormLayout;
-class VectorDescriptor;
+class VectorProperty;
 
 //! Polarization analysis editor (beam polarization, analyzer properties) for instrument editors.
 //! Operates on Instrument2DItem.
@@ -37,7 +37,7 @@ signals:
 
 private:
     DoubleSpinBox* createSpinBox(const DoubleDescriptor& d);
-    void addVector(QFormLayout* parentLayout, const VectorDescriptor& d);
+    void addVector(QFormLayout* parentLayout, const VectorProperty& d);
 
     InstrumentItem* m_instrument;
 };
diff --git a/GUI/View/SampleDesigner/CompoundForm.cpp b/GUI/View/SampleDesigner/CompoundForm.cpp
index cc675281c47c6ba0264e20de9ab5412eb4ac4159..a68b5f95ab21d7cc13225b0ceb1655c5f04c4615 100644
--- a/GUI/View/SampleDesigner/CompoundForm.cpp
+++ b/GUI/View/SampleDesigner/CompoundForm.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/View/SampleDesigner/CompoundForm.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/CompoundItem.h"
 #include "GUI/Util/ActionFactory.h"
 #include "GUI/View/SampleDesigner/FormLayouter.h"
diff --git a/GUI/View/SampleDesigner/CoreAndShellForm.cpp b/GUI/View/SampleDesigner/CoreAndShellForm.cpp
index c25225e3c215ea27c5e90975a52c5a23d0c1d69d..8a132d9ff5a997bbd9f7f5fbb5e831bfcbee7d24 100644
--- a/GUI/View/SampleDesigner/CoreAndShellForm.cpp
+++ b/GUI/View/SampleDesigner/CoreAndShellForm.cpp
@@ -14,7 +14,6 @@
 
 #include "GUI/View/SampleDesigner/CoreAndShellForm.h"
 #include "GUI/Model/CatSample/FormFactorItemCatalog.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/CoreAndShellItem.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
 #include "GUI/Model/Sample/ParticleItem.h"
diff --git a/GUI/View/SampleDesigner/FormLayouter.cpp b/GUI/View/SampleDesigner/FormLayouter.cpp
index fd969e9fa3a89e7863bc231693cdc4ac8689f747..5b1c5e34d023ebd0b81a22587eb19a0b4afdfa9b 100644
--- a/GUI/View/SampleDesigner/FormLayouter.cpp
+++ b/GUI/View/SampleDesigner/FormLayouter.cpp
@@ -14,7 +14,7 @@
 
 #include "GUI/View/SampleDesigner/FormLayouter.h"
 #include "Base/Util/Assert.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
+#include "GUI/Model/Descriptor/VectorProperty.h"
 #include "GUI/View/Common/DoubleSpinBox.h"
 #include "GUI/View/SampleDesigner/LayerEditorUtils.h"
 #include "GUI/View/SampleDesigner/SampleEditorController.h"
@@ -89,7 +89,7 @@ int FormLayouter::addGroupOfValues(const QString& labelText, const DoubleDescrip
     return addRow(labelText, w);
 }
 
-int FormLayouter::addVector(const VectorDescriptor& d, bool vertically /*= true*/)
+int FormLayouter::addVector(const VectorProperty& d, bool vertically /*= true*/)
 {
     auto* w = new QWidget(m_formLayout->parentWidget());
     w->setObjectName("PropertyBaseWidget");
@@ -100,10 +100,10 @@ int FormLayouter::addVector(const VectorDescriptor& d, bool vertically /*= true*
     gridLayout->setContentsMargins(0, 0, 0, 0);
     gridLayout->setSpacing(6);
 
-    LayerEditorUtils::addMultiPropertyToGrid(gridLayout, 0, {d.x, d.y, d.z}, m_ec, vertically,
+    LayerEditorUtils::addMultiPropertyToGrid(gridLayout, 0, {d.x(), d.y(), d.z()}, m_ec, vertically,
                                              true);
 
-    return addRow(d.label, w);
+    return addRow(d.label(), w);
 }
 
 void FormLayouter::setRowVisible(int row, bool visible)
diff --git a/GUI/View/SampleDesigner/FormLayouter.h b/GUI/View/SampleDesigner/FormLayouter.h
index 96fd3bf24257f33822fc192573d08d1b45760383..0ea7d56d75bdc82ac8d9e0ec41efc5ae83f4d64b 100644
--- a/GUI/View/SampleDesigner/FormLayouter.h
+++ b/GUI/View/SampleDesigner/FormLayouter.h
@@ -25,7 +25,7 @@ class QString;
 class QWidget;
 class QSpinBox;
 class SampleEditorController;
-class VectorDescriptor;
+class VectorProperty;
 
 //! Utility class to populate a QFormLayout.
 //!
@@ -133,7 +133,7 @@ public:
     //! In addition, the caller can define whether the labels are above the values
     //! (vertically=true), or whether labels and values are all placed in one row
     //! (vertically=false).
-    int addVector(const VectorDescriptor& d, bool vertically = true);
+    int addVector(const VectorProperty& d, bool vertically = true);
 
     //! Shows or hides the widgets in a row.
     void setRowVisible(int row, bool visible);
diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.cpp b/GUI/View/SampleDesigner/LayerEditorUtils.cpp
index 97a5d1830908294223129549f83c17fe9aead189..14cc40f90abfa04cd2ae8d38d55de747f99a6130 100644
--- a/GUI/View/SampleDesigner/LayerEditorUtils.cpp
+++ b/GUI/View/SampleDesigner/LayerEditorUtils.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/View/SampleDesigner/LayerEditorUtils.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/CompoundItem.h"
 #include "GUI/Model/Sample/CoreAndShellItem.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
@@ -123,19 +122,20 @@ void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int fir
 }
 
 void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol,
-                                       const VectorDescriptor& v, SampleEditorController* ec,
+                                       const VectorProperty& v, SampleEditorController* ec,
                                        bool vertically, bool addSpacer)
 {
-    addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x, v.y, v.z}, ec, vertically, addSpacer);
+    addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x(), v.y(), v.z()}, ec, vertically,
+                           addSpacer);
 }
 
 
 void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol,
-                                       const VectorDescriptor& v,
+                                       const VectorProperty& v,
                                        function<void(double, DoubleDescriptor)> setNewValue,
                                        bool vertically, bool addSpacer)
 {
-    addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x, v.y, v.z}, setNewValue, vertically,
+    addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x(), v.y(), v.z()}, setNewValue, vertically,
                            addSpacer);
 }
 
diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.h b/GUI/View/SampleDesigner/LayerEditorUtils.h
index 18c04e26892ba8396cc7a0fbda139a18ccbd4838..25854f96b220d64bf08a33078add122565baba02 100644
--- a/GUI/View/SampleDesigner/LayerEditorUtils.h
+++ b/GUI/View/SampleDesigner/LayerEditorUtils.h
@@ -35,7 +35,7 @@ class QString;
 class QWidget;
 class RotationItem;
 class SampleEditorController;
-class VectorDescriptor;
+class VectorProperty;
 class Profile2DItem;
 
 //! Utility functions to support layer oriented sample editor
@@ -62,11 +62,11 @@ void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
 
 //! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to
 //! SampleEditorController::setDouble()
-void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, const VectorDescriptor& v,
+void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, const VectorProperty& v,
                      SampleEditorController* ec, bool vertically, bool addSpacer);
 
 //! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to the given setNewValue()
-void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, const VectorDescriptor& v,
+void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, const VectorProperty& v,
                      std::function<void(double, DoubleDescriptor)> setNewValue, bool vertically,
                      bool addSpacer);
 
diff --git a/GUI/View/SampleDesigner/MaterialInplaceForm.cpp b/GUI/View/SampleDesigner/MaterialInplaceForm.cpp
index 31482c44f79ec5dc476299bed5f892b51a0812c6..3609e91ca01fab6a3cdf7ec9e9e1352eb6b57660 100644
--- a/GUI/View/SampleDesigner/MaterialInplaceForm.cpp
+++ b/GUI/View/SampleDesigner/MaterialInplaceForm.cpp
@@ -15,7 +15,6 @@
 #include "GUI/View/SampleDesigner/MaterialInplaceForm.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Descriptor/DoubleDescriptor.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/ItemWithMaterial.h"
 #include "GUI/Model/Sample/MaterialItem.h"
 #include "GUI/Model/Sample/MaterialItems.h"
@@ -113,7 +112,7 @@ void MaterialInplaceForm::createWidgets()
     }
 
     // -- Create UI for magnetization vector
-    VectorDescriptor mag = material->magnetizationVector();
+    VectorProperty mag = material->magnetizationVector();
     const auto setNewValue = [=](double value, DoubleDescriptor d) {
         m_ec->setMaterialValue(m_item, value, d);
     };
diff --git a/GUI/View/SampleDesigner/MesocrystalForm.cpp b/GUI/View/SampleDesigner/MesocrystalForm.cpp
index 2fd582c6fe153b63fad78757c06ff90730c3e6a2..314f7f9b3e06747e0863ed562d16d2f8c7cce690 100644
--- a/GUI/View/SampleDesigner/MesocrystalForm.cpp
+++ b/GUI/View/SampleDesigner/MesocrystalForm.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/View/SampleDesigner/MesocrystalForm.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
 #include "GUI/Model/Sample/MesocrystalItem.h"
 #include "GUI/Model/Sample/ParticleItem.h"
diff --git a/GUI/View/SampleDesigner/ParticleForm.cpp b/GUI/View/SampleDesigner/ParticleForm.cpp
index df6a185424c035e4979d5778e1d5e8faa43bfe66..cda81fb8da22771de6b04a0a2f99314b2e28a747 100644
--- a/GUI/View/SampleDesigner/ParticleForm.cpp
+++ b/GUI/View/SampleDesigner/ParticleForm.cpp
@@ -14,7 +14,6 @@
 
 #include "GUI/View/SampleDesigner/ParticleForm.h"
 #include "GUI/Model/CatSample/FormFactorItemCatalog.h"
-#include "GUI/Model/Descriptor/VectorDescriptor.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
 #include "GUI/Model/Sample/ParticleItem.h"
 #include "GUI/Util/ActionFactory.h"