diff --git a/GUI/Model/Descriptor/SelectionDescriptor.h b/GUI/Model/Descriptor/SelectionDescriptor.h
deleted file mode 100644
index 697ea680ed7ff31bbc582675473fed42d872765f..0000000000000000000000000000000000000000
--- a/GUI/Model/Descriptor/SelectionDescriptor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Descriptor/SelectionDescriptor.h
-//! @brief     Defines class SelectionDescriptor
-//!
-//! @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_SELECTIONDESCRIPTOR_H
-#define BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONDESCRIPTOR_H
-
-#include "GUI/Util/ComboProperty.h"
-#include <QString>
-#include <QStringList>
-#include <functional>
-
-//! Abstract base class for SelectionDescriptor to ease referencing.
-class AbstractSelectionDescriptor {
-public:
-    virtual ~AbstractSelectionDescriptor() = default;
-
-    //! Set currently selected option
-    virtual void setCurrentIndex(int newIndex) const = 0;
-
-    //! Get currently selected option
-    virtual int currentIndex() const = 0;
-};
-
-//! Describes a selection (various possibilities and the current one).
-//!
-//! Usually a selection is presented as a combo box.
-//!
-//! SelectionDescriptor operate on a SelectionProperty. Please refer to this class for more
-//! information.
-//!
-//! The template parameter defines the type of the current item. This can be a pointer to a common
-//! base class (like RotationItem*), but it also can be a std::variant<...>, which is useful if
-//! no dedicated common base class exists (like for the roughness items LayerZeroRoughnessItem and
-//! LayerBasicRoughnessItem).
-//! If used with a ComboProperty holder, the template parameter can be a QString, so currentItem()
-//! returns the currently selected string.
-//!
-//! Note that this class does not provide (*implement*) a selection, but *provide
-//! information* about a selection. For implementing a selection, please see SelectionProperty.
-//!
-//! For easy UI creation, there are functions like GUI:Util::createSelectionCombo() which take a
-//! descriptor and fully initialize the created combo box.
-//!
-//! \sa SelectionProperty
-//!
-template <typename T>
-class SelectionDescriptor : public AbstractSelectionDescriptor {
-public:
-    SelectionDescriptor() = default;
-
-    operator T() const { return currentItem(); }
-
-    void setCurrentIndex(int newIndex) const override { currentIndexSetter(newIndex); }
-
-    int currentIndex() const override { return currentIndexGetter(); }
-
-    QString label;       //!< A label text (short, no trailing colon)
-    QString tooltip;     //!< Tooltip text
-    QStringList options; //!< List of options, usually presented as combo entries
-    std::function<void(int)> currentIndexSetter; //!< Function to set currently selected option
-    std::function<int()> currentIndexGetter;     //!< Function to get currently selected option
-    std::function<T()> currentItem;              //!< Function to get currently selected item
-};
-
-#endif // BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONDESCRIPTOR_H
diff --git a/GUI/Model/Descriptor/SelectionProperty.h b/GUI/Model/Descriptor/SelectionProperty.h
index e35dd80d43bb5d39d175a70a110bfb06bf3aa36b..3af069b987bf409bb0fccfd4638553bb6335163f 100644
--- a/GUI/Model/Descriptor/SelectionProperty.h
+++ b/GUI/Model/Descriptor/SelectionProperty.h
@@ -15,9 +15,20 @@
 #ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H
 #define BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H
 
-#include "GUI/Model/Descriptor/SelectionDescriptor.h"
 #include "GUI/Support/XML/Streamer.h"
 
+//! Abstract base class for SelectionProperty to ease referencing.
+class AbstractSelectionProperty {
+public:
+    virtual ~AbstractSelectionProperty() = default;
+
+    //! Set currently selected option
+    virtual void setCurrentIndex(int newIndex) = 0;
+
+    //! Get currently selected option
+    virtual int currentIndex() const = 0;
+};
+
 //! Class for representing a selection, its attributes and its accessors.
 //!
 //! A "selection" in this context is a class instance out of a range of possible class instances.
@@ -34,22 +45,13 @@
 //! pointer is handled in here.
 //! * label: a label of e.g. a spin box
 //! * tooltip: tooltip for e.g. a spin box
-//! * persistent tag: a name to serialize this property. Do not change this string, since it is
-//!   serialized!
-//! * A list of available options (e.g. the names of the distributions)
-//! * A descriptor which provides some of the given information, as well as getters/setters.
+//! * a list of available options (e.g. the names of the distributions)
+//! * setters and getters
 //!
-//! For the initialization of a SelectionProperty there are helper methods. They are not necessarily
-//! to be called if they are not convenient. They are only there to help initialization e.g by using
-//! a catalog. If no catalog exists for the given case, the initialization can be done by any means.
-//!
-//! This means especially that this class is **not** relying on the existence of a related catalog
-//! class - a catalog helps but is not mandatory.
-//!
-//! \sa SelectionDescriptor
+//! The initialization of a SelectionProperty is done using a catalog.
 //!
 template <typename Catalog>
-class SelectionProperty {
+class SelectionProperty : public AbstractSelectionProperty {
 public:
     using CatalogedType = typename Catalog::CatalogedType;
 
@@ -61,8 +63,8 @@ public:
     template <typename... ArgsForCreation>
     void init(const QString& label, const QString& tooltip, ArgsForCreation... argsForCreation)
     {
-        initDescriptor(label, tooltip, argsForCreation...);
-        m_descriptor.setCurrentIndex(0);
+        initFieldsAndSetter(label, tooltip, argsForCreation...);
+        setCurrentIndex(0);
     }
 
     //! Initialize by means of a catalog class and an initializer function.
@@ -82,8 +84,8 @@ public:
     {
         m_initializer = initializer;
 
-        initDescriptor(label, tooltip);
-        m_descriptor.setCurrentIndex(0);
+        initFieldsAndSetter(label, tooltip);
+        setCurrentIndex(0);
     }
 
     //! Initialize by means of a catalog class, a subsection of allowed types and an initializer
@@ -106,21 +108,18 @@ public:
         m_initializer = initializer;
         m_types = types;
 
-        initDescriptor(label, tooltip);
-        m_descriptor.setCurrentIndex(0);
+        initFieldsAndSetter(label, tooltip);
+        setCurrentIndex(0);
     }
 
-    //! Cast to a descriptor working on this property.
-    operator SelectionDescriptor<CatalogedType*>() const { return m_descriptor; }
-
     //! Direct access to the stored pointer
     CatalogedType* operator->() const { return m_p.get(); }
 
     //! Direct access to the stored pointer
-    CatalogedType* get() const { return m_p.get(); }
+    CatalogedType* currentItem() const { return m_p.get(); }
 
     //! Directly set the new item.
-    void set(CatalogedType* t, bool callInitializer = false)
+    void setCurrentItem(CatalogedType* t, bool callInitializer = false)
     {
         if (callInitializer && m_initializer)
             m_initializer(t, m_p.get());
@@ -129,7 +128,7 @@ public:
 
     //! Directly set the new item.
     template <typename S, typename... ArgsForConstructor>
-    S* set(ArgsForConstructor... argsForConstructor)
+    S* setCurrentItem(ArgsForConstructor... argsForConstructor)
     {
         S* s = new S(argsForConstructor...);
         if (s != nullptr && m_initializer)
@@ -141,47 +140,52 @@ public:
     template <typename... ArgsForCreation>
     void rwSelected(Streamer& s, const QString& tag, ArgsForCreation... argsForCreation)
     {
-        if (QXmlStreamWriter* w = s.xmlWriter()) {
+        if (s.xmlWriter()) {
             s.write<Catalog>(tag, m_p.get());
-        } else if (QXmlStreamReader* r = s.xmlReader()) {
+        } else if (s.xmlReader()) {
             CatalogedType* p = nullptr;
             s.read<Catalog>(tag, p, argsForCreation...);
             m_p.reset(p);
         }
     }
 
+    QString label() const { return m_label; }
+    QString tooltip() const { return m_tooltip; }
+    QStringList options() const { return m_options; }
+
+    void setCurrentIndex(int newIndex) override { currentIndexSetter(newIndex); }
+    int currentIndex() const override { return m_types.indexOf(Catalog::type(m_p.get())); }
+
 private:
     template <typename... ArgsForCreation>
-    void initDescriptor(const QString& label, const QString& tooltip,
-                        ArgsForCreation... argsForCreation)
-
+    void initFieldsAndSetter(const QString& label, const QString& tooltip,
+                             ArgsForCreation... argsForCreation)
     {
-        auto setCurrentIndex = [=](int current) {
+        m_label = label;
+        m_tooltip = tooltip;
+        m_options.clear();
+        for (const auto type : m_types)
+            m_options << Catalog::uiInfo(type).menuEntry;
+
+        currentIndexSetter = [=](int current) {
             auto* p = Catalog::create(m_types[current], argsForCreation...);
             if (m_initializer)
                 m_initializer(p, m_p.get());
             m_p.reset(p);
         };
-
-        m_descriptor.label = label;
-        m_descriptor.tooltip = tooltip;
-        for (const auto type : m_types)
-            m_descriptor.options << Catalog::uiInfo(type).menuEntry;
-        m_descriptor.currentIndexSetter = setCurrentIndex;
-        m_descriptor.currentIndexGetter = [=]() {
-            return m_types.indexOf(Catalog::type(m_p.get()));
-        };
-        m_descriptor.currentItem = [=] { return m_p.get(); };
     }
 
 private:
-    SelectionDescriptor<CatalogedType*>
-        m_descriptor; //!< descriptor, holding attributes like label, tooltip
-
     std::unique_ptr<CatalogedType> m_p; //!< Current selection
 
+    QString m_label;       //!< A label text (short, no trailing colon)
+    QString m_tooltip;     //!< Tooltip text
+    QStringList m_options; //!< List of options, usually presented as combo entries
     QVector<typename Catalog::Type> m_types = Catalog::types();
 
+    //! Reimplementable function to set currently selected option.
+    std::function<void(int)> currentIndexSetter = nullptr;
+
     //! initializer function. Can be empty.
     //! The first argument is the new item, the second is the old one if present; can be null.
     //! This is intended to maybe copy values from the old to the new selection. oldItem also can be
diff --git a/GUI/Model/Device/BeamDistributionItem.cpp b/GUI/Model/Device/BeamDistributionItem.cpp
index 61bc6342e68c084ea72bdfa6fdeb2aabcac7f7c0..71c6c8c8630813258ddce037d6bd8db73dec4cf3 100644
--- a/GUI/Model/Device/BeamDistributionItem.cpp
+++ b/GUI/Model/Device/BeamDistributionItem.cpp
@@ -19,7 +19,7 @@
 std::unique_ptr<ParameterDistribution> BeamDistributionItem::getParameterDistributionForName(
     ParameterDistribution::WhichParameter which) const
 {
-    if (const auto* d = distribution()) {
+    if (const auto* d = distributionItem()) {
         auto distribution1D = createDistribution1D();
 
         if (distribution1D) {
@@ -39,14 +39,14 @@ double BeamDistributionItem::meanValue() const
     std::unique_ptr<IDistribution1D> domainDistr = createDistribution1D();
     if (domainDistr)
         return domainDistr->mean() / scaleFactor();
-    return dynamic_cast<SymmetricResolutionItem*>(distribution())->mean();
+    return dynamic_cast<SymmetricResolutionItem*>(distributionItem())->mean();
 }
 
 void BeamDistributionItem::resetToValue(double value)
 {
     auto* d = new DistributionNoneItem();
     d->setMean(value);
-    m_distribution.set(d);
+    m_distribution.setCurrentItem(d);
 }
 
 double BeamDistributionItem::scaleFactor() const
@@ -54,22 +54,7 @@ double BeamDistributionItem::scaleFactor() const
     return 1.0;
 }
 
-DistributionItem* BeamDistributionItem::distribution() const
-{
-    return m_distribution.get();
-}
-
-SelectionDescriptor<DistributionItem*> BeamDistributionItem::distributionSelection() const
-{
-    return m_distribution;
-}
-
-void BeamDistributionItem::setDistribution(DistributionItem* d)
-{
-    m_distribution.set(d);
-}
-
 std::unique_ptr<IDistribution1D> BeamDistributionItem::createDistribution1D() const
 {
-    return distribution()->createDistribution(scaleFactor());
+    return distributionItem()->createDistribution(scaleFactor());
 }
diff --git a/GUI/Model/Device/BeamDistributionItem.h b/GUI/Model/Device/BeamDistributionItem.h
index ccba2f001390ca2b4bad5e6fbdb49a53bb819131..f1247995ccadf904ffea9ca4625ee11b2e1d1f3c 100644
--- a/GUI/Model/Device/BeamDistributionItem.h
+++ b/GUI/Model/Device/BeamDistributionItem.h
@@ -39,9 +39,8 @@ public:
 
     template <typename T>
     T* setDistributionType();
-    DistributionItem* distribution() const;
-    SelectionDescriptor<DistributionItem*> distributionSelection() const;
-    void setDistribution(DistributionItem* d);
+    DistributionItem* distributionItem() const { return m_distribution.currentItem(); }
+    SelectionProperty<DistributionItemCatalog>& distribution() { return m_distribution; }
 
 protected:
     virtual std::unique_ptr<IDistribution1D> createDistribution1D() const;
@@ -52,8 +51,8 @@ protected:
 template <typename T>
 T* BeamDistributionItem::setDistributionType()
 {
-    m_distribution.set<T>();
-    return dynamic_cast<T*>(m_distribution.get());
+    m_distribution.setCurrentItem<T>();
+    return dynamic_cast<T*>(m_distribution.currentItem());
 }
 
 #endif // BORNAGAIN_GUI_MODEL_DEVICE_BEAMDISTRIBUTIONITEM_H
diff --git a/GUI/Model/Device/BeamItems.cpp b/GUI/Model/Device/BeamItems.cpp
index 5071c4df50f6a90101af31f662711558ce54ce6d..3d2593853cfc8de0a8ce732bbc740651768fa35d 100644
--- a/GUI/Model/Device/BeamItems.cpp
+++ b/GUI/Model/Device/BeamItems.cpp
@@ -168,24 +168,14 @@ BasicAxisItem* SpecularBeamItem::inclinationAxis() const
     return inclinationAngleItem()->alphaAxis();
 }
 
-FootprintItem* SpecularBeamItem::footprint() const
-{
-    return m_footprint.get();
-}
-
-SelectionDescriptor<FootprintItem*> SpecularBeamItem::footprintSelection() const
-{
-    return m_footprint;
-}
-
 void SpecularBeamItem::setGaussianFootprint(double value)
 {
-    m_footprint.set(new FootprintGaussianItem(value));
+    m_footprint.setCurrentItem(new FootprintGaussianItem(value));
 }
 
 void SpecularBeamItem::setSquareFootprint(double value)
 {
-    m_footprint.set(new FootprintSquareItem(value));
+    m_footprint.setCurrentItem(new FootprintSquareItem(value));
 }
 
 void SpecularBeamItem::updateToData(const IAxis& axis, QString units)
diff --git a/GUI/Model/Device/BeamItems.h b/GUI/Model/Device/BeamItems.h
index d781482fd0b5a95a562f34915c89d8f779d9da01..8e893fa249d101114eddd08543087e72b951938e 100644
--- a/GUI/Model/Device/BeamItems.h
+++ b/GUI/Model/Device/BeamItems.h
@@ -16,7 +16,6 @@
 #define BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H
 
 #include "GUI/Model/CatDevice/FootprintItemCatalog.h"
-#include "GUI/Model/Descriptor/SelectionDescriptor.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Device/BeamAngleItems.h"
 #include "GUI/Model/Device/BeamWavelengthItem.h"
@@ -80,12 +79,10 @@ public:
     SpecularBeamInclinationItem* inclinationAngleItem() const override;
     BasicAxisItem* inclinationAxis() const;
 
-    FootprintItem* footprint() const;
-    SelectionDescriptor<FootprintItem*> footprintSelection() const;
+    SelectionProperty<FootprintItemCatalog>& footprint() { return m_footprint; }
+
     void setGaussianFootprint(double value);
     void setSquareFootprint(double value);
-    template <typename T>
-    T* setFootprintType();
 
     void updateToData(const IAxis& axis, QString units);
     void updateWavelength();
diff --git a/GUI/Model/Device/BeamWavelengthItem.cpp b/GUI/Model/Device/BeamWavelengthItem.cpp
index 358b8e0769820cd302f27a72a088f8fa749a30a1..db7f8371752dc4ee4336cd710204aaf865db29e0 100644
--- a/GUI/Model/Device/BeamWavelengthItem.cpp
+++ b/GUI/Model/Device/BeamWavelengthItem.cpp
@@ -85,7 +85,7 @@ SpecularBeamWavelengthItem::SpecularBeamWavelengthItem()
 
 void SpecularBeamWavelengthItem::setToRange(const RealLimits& limits)
 {
-    if (auto* symmetricDistribution = dynamic_cast<SymmetricResolutionItem*>(distribution())) {
+    if (auto* symmetricDistribution = dynamic_cast<SymmetricResolutionItem*>(distributionItem())) {
         if (!limits.isInRange(wavelength())) {
             const double new_value =
                 limits.isLimited() ? (limits.upperLimit() - limits.lowerLimit()) / 2. : default_wl;
diff --git a/GUI/Model/Device/DetectorItems.cpp b/GUI/Model/Device/DetectorItems.cpp
index da7f88f39ed3dd7ab6bbaa550fc8868d7c99d60b..2180cfa06ef83a0fa70abc8048cf3f84892e5088 100644
--- a/GUI/Model/Device/DetectorItems.cpp
+++ b/GUI/Model/Device/DetectorItems.cpp
@@ -43,12 +43,7 @@ MaskItems& DetectorItem::maskItems()
     return m_maskItems;
 }
 
-ResolutionFunctionItem* DetectorItem::resolutionFunction() const
-{
-    return m_resolutionFunction.get();
-}
-
-SelectionDescriptor<ResolutionFunctionItem*> DetectorItem::resolutionFunctionSelection() const
+SelectionProperty<ResolutionFunctionItemCatalog>& DetectorItem::resolutionFunction()
 {
     return m_resolutionFunction;
 }
diff --git a/GUI/Model/Device/DetectorItems.h b/GUI/Model/Device/DetectorItems.h
index 7bcef7153858b8d033b49366eb4fd4345d1d9ea3..704f9ba4aba9e4799627ba2eddd26158ec87cb7b 100644
--- a/GUI/Model/Device/DetectorItems.h
+++ b/GUI/Model/Device/DetectorItems.h
@@ -49,8 +49,8 @@ public:
     void importMasks(const MaskContainerItem* maskContainer);
     MaskItems& maskItems();
 
-    ResolutionFunctionItem* resolutionFunction() const;
-    SelectionDescriptor<ResolutionFunctionItem*> resolutionFunctionSelection() const;
+    SelectionProperty<ResolutionFunctionItemCatalog>& resolutionFunction();
+
     template <typename T>
     T* setResolutionFunctionType();
 
@@ -73,8 +73,8 @@ protected:
 template <typename T>
 T* DetectorItem::setResolutionFunctionType()
 {
-    m_resolutionFunction.set<T>();
-    return dynamic_cast<T*>(m_resolutionFunction.get());
+    m_resolutionFunction.setCurrentItem<T>();
+    return dynamic_cast<T*>(m_resolutionFunction.currentItem());
 }
 
 #endif // BORNAGAIN_GUI_MODEL_DEVICE_DETECTORITEMS_H
diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp
index a8f4dd773f4807ec46fab38428b9ba752891e3be..607be6c9202a4476ff3d8d8381c06ed00af73072 100644
--- a/GUI/Model/Device/InstrumentItems.cpp
+++ b/GUI/Model/Device/InstrumentItems.cpp
@@ -85,7 +85,7 @@ InstrumentItem::InstrumentItem()
                         "polarization");
     m_analyzerDirection.init("Analyzer direction", "Direction of the polarization analysis",
                              Unit::unitless, "analyzerDirection");
-    m_backgroundItem.init("Background", "");
+    m_background.init("Background", "");
 }
 
 InstrumentItem* InstrumentItem::createCopy() const
@@ -96,51 +96,11 @@ InstrumentItem* InstrumentItem::createCopy() const
     return copy;
 }
 
-QString InstrumentItem::id() const
-{
-    return m_id;
-}
-
-void InstrumentItem::setId(const QString& id)
-{
-    m_id = id;
-}
-
-void InstrumentItem::setInstrumentName(const QString& instrumentName)
-{
-    m_name = instrumentName;
-}
-
-QString InstrumentItem::instrumentName() const
-{
-    return m_name;
-}
-
-QString InstrumentItem::description() const
-{
-    return m_description;
-}
-
-void InstrumentItem::setDescription(const QString& description)
-{
-    m_description = description;
-}
-
 BeamItem* InstrumentItem::beamItem() const
 {
     return m_beamItem.get();
 }
 
-BackgroundItem* InstrumentItem::backgroundItem() const
-{
-    return m_backgroundItem.get();
-}
-
-SelectionDescriptor<BackgroundItem*> InstrumentItem::backgroundSelection() const
-{
-    return m_backgroundItem;
-}
-
 bool InstrumentItem::alignedWith(const RealItem* item) const
 {
     return shape() == item->shape();
@@ -173,7 +133,7 @@ void InstrumentItem::serialize(Streamer& s)
     m_analyzerDirection.rwProperty(s, Tag::AnalyzerDirection);
     Serialize::rwProperty(s, Tag::AnalyzerEfficiency, m_analyzerEfficiency);
     Serialize::rwProperty(s, Tag::AnalyzerTotalTransmission, m_analyzerTotalTransmission);
-    m_backgroundItem.rwSelected(s, Tag::Background);
+    m_background.rwSelected(s, Tag::Background);
     Serialize::rwClass(s, Tag::Beam, *m_beamItem);
 }
 
@@ -352,24 +312,14 @@ const ICoordSystem* DepthProbeInstrumentItem::createCoordSystem() const
 Instrument2DItem::Instrument2DItem()
 {
     m_beamItem.reset(new GISASBeamItem());
-    m_detectorItem.init("Detector", "");
+    m_detector.init("Detector", "");
 }
 
 void Instrument2DItem::serialize(Streamer& s)
 {
     s.assertVersion(0);
     Serialize::rwBaseClass<InstrumentItem>(s, "InstrumentItem", this);
-    m_detectorItem.rwSelected(s, Tag::Detector);
-}
-
-DetectorItem* Instrument2DItem::detectorItem() const
-{
-    return m_detectorItem.get();
-}
-
-SelectionDescriptor<DetectorItem*> Instrument2DItem::detectorSelection() const
-{
-    return m_detectorItem;
+    m_detector.rwSelected(s, Tag::Detector);
 }
 
 void Instrument2DItem::importMasks(const MaskContainerItem* maskContainer)
diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h
index 9a5b13ebb8afb033c1d5944e18cd510bff2f19ba..ba919d309ac885293e68d32dca91bbed5f3d3c94 100644
--- a/GUI/Model/Device/InstrumentItems.h
+++ b/GUI/Model/Device/InstrumentItems.h
@@ -18,7 +18,6 @@
 #include "GUI/Model/CatDevice/BackgroundItemCatalog.h"
 #include "GUI/Model/CatDevice/DetectorItemCatalog.h"
 #include "GUI/Model/Descriptor/AxisProperty.h"
-#include "GUI/Model/Descriptor/SelectionDescriptor.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Descriptor/VectorProperty.h"
 #include "GUI/Model/Device/BackgroundItems.h"
@@ -50,11 +49,11 @@ public:
 
     virtual void serialize(Streamer& s);
 
-    QString id() const;
-    void setId(const QString& id);
+    QString id() const { return m_id; }
+    void setId(const QString& id) { m_id = id; }
 
-    void setInstrumentName(const QString& instrumentName);
-    QString instrumentName() const;
+    QString instrumentName() const { return m_name; }
+    void setInstrumentName(const QString& instrumentName) { m_name = instrumentName; }
 
     //! The type as how to show it on the UI. Do not use for type checking or similar!
     virtual QString instrumentType() const = 0;
@@ -65,15 +64,15 @@ public:
         return dynamic_cast<const T*>(this) != nullptr;
     }
 
-    QString description() const;
-    void setDescription(const QString& description);
+    QString description() const { return m_description; }
+    void setDescription(const QString& description) { m_description = description; }
 
     virtual BeamItem* beamItem() const;
-    BackgroundItem* backgroundItem() const;
 
     template <typename T>
     T* setBackgroundType();
-    SelectionDescriptor<BackgroundItem*> backgroundSelection() const;
+    SelectionProperty<BackgroundItemCatalog>& background() { return m_background; }
+    BackgroundItem* backgroundItem() const { return m_background.currentItem(); }
 
     virtual std::vector<int> shape() const = 0;
 
@@ -116,7 +115,7 @@ protected:
     QString m_name;
     QString m_description;
     bool m_withPolarizerAnalyzer;
-    SelectionProperty<BackgroundItemCatalog> m_backgroundItem;
+    SelectionProperty<BackgroundItemCatalog> m_background;
     std::unique_ptr<BeamItem> m_beamItem;
 
     VectorProperty m_polarization;
@@ -174,10 +173,10 @@ class Instrument2DItem : public InstrumentItem {
 public:
     void serialize(Streamer& s) override;
 
-    DetectorItem* detectorItem() const;
     template <typename T>
     T* setDetectorType();
-    SelectionDescriptor<DetectorItem*> detectorSelection() const;
+    DetectorItem* detectorItem() const { return m_detector.currentItem(); }
+    SelectionProperty<DetectorItemCatalog>& detector() { return m_detector; }
 
     void importMasks(const MaskContainerItem* maskContainer) override;
 
@@ -190,7 +189,7 @@ public:
 protected:
     Instrument2DItem();
 
-    SelectionProperty<DetectorItemCatalog> m_detectorItem;
+    SelectionProperty<DetectorItemCatalog> m_detector;
 };
 
 
@@ -232,15 +231,15 @@ protected:
 template <typename T>
 T* InstrumentItem::setBackgroundType()
 {
-    m_backgroundItem.set<T>();
-    return dynamic_cast<T*>(m_backgroundItem.get());
+    m_background.setCurrentItem<T>();
+    return dynamic_cast<T*>(m_background.currentItem());
 }
 
 template <typename T>
 T* Instrument2DItem::setDetectorType()
 {
-    m_detectorItem.set<T>();
-    return dynamic_cast<T*>(m_detectorItem.get());
+    m_detector.setCurrentItem<T>();
+    return dynamic_cast<T*>(m_detector.currentItem());
 }
 
 #endif // BORNAGAIN_GUI_MODEL_DEVICE_INSTRUMENTITEMS_H
diff --git a/GUI/Model/Device/RectangularDetectorItem.h b/GUI/Model/Device/RectangularDetectorItem.h
index 71a1a4ace12e4cd4eed68f3e0e9e4c61f26be599..9e271576ce69909e5d17171861a1606e7da667ae 100644
--- a/GUI/Model/Device/RectangularDetectorItem.h
+++ b/GUI/Model/Device/RectangularDetectorItem.h
@@ -18,6 +18,7 @@
 #include "Device/Detector/RectangularDetector.h"
 #include "GUI/Model/Descriptor/VectorProperty.h"
 #include "GUI/Model/Device/DetectorItems.h"
+#include "GUI/Util/ComboProperty.h"
 
 class RectangularDetectorItem : public DetectorItem {
 public:
diff --git a/GUI/Model/FromCore/ItemizeSample.cpp b/GUI/Model/FromCore/ItemizeSample.cpp
index 6e7d1c79dbff2700e47f21c2a6975cabffe33952..7e9ecb11dfe6cd65583e1eb3a2d0b9ecb83c4c04 100644
--- a/GUI/Model/FromCore/ItemizeSample.cpp
+++ b/GUI/Model/FromCore/ItemizeSample.cpp
@@ -134,20 +134,20 @@ void setDecayFunction1D(Interference1DLatticeItem* parent, const IProfile1D* ipd
     if (const auto* pdf = dynamic_cast<const Profile1DCauchy*>(ipdf)) {
         auto* item = new Profile1DCauchyItem();
         item->setOmega(pdf->omega());
-        parent->setDecayFunction(item);
+        parent->setDecayFunctionType(item);
     } else if (const auto* pdf = dynamic_cast<const Profile1DGauss*>(ipdf)) {
         auto* item = new Profile1DGaussItem();
         item->setOmega(pdf->omega());
-        parent->setDecayFunction(item);
+        parent->setDecayFunctionType(item);
     } else if (const auto* pdf = dynamic_cast<const Profile1DTriangle*>(ipdf)) {
         auto* item = new Profile1DTriangleItem();
         item->setOmega(pdf->omega());
-        parent->setDecayFunction(item);
+        parent->setDecayFunctionType(item);
     } else if (const auto* pdf = dynamic_cast<const Profile1DVoigt*>(ipdf)) {
         auto* item = new Profile1DVoigtItem();
         item->setOmega(pdf->omega());
         item->setEta(pdf->eta());
-        parent->setDecayFunction(item);
+        parent->setDecayFunctionType(item);
     } else
         throw Error("GUI::Transform::FromCore::setDecayFunction1D: -> Error");
 }
@@ -324,25 +324,25 @@ void setLayerItem(LayerItem* parent, const Layer* layer, const LayerInterface* t
 void setRotation(ItemWithParticles* parent, const IRotation* rotation)
 {
     if (!rotation)
-        parent->setRotation(nullptr);
+        parent->setRotationType(nullptr);
     else if (const auto* r = dynamic_cast<const RotationX*>(rotation)) {
         auto* item = new XRotationItem();
         item->setAngle(Units::rad2deg(r->angle()));
-        parent->setRotation(item);
+        parent->setRotationType(item);
     } else if (const auto* r = dynamic_cast<const RotationY*>(rotation)) {
         auto* item = new YRotationItem();
         item->setAngle(Units::rad2deg(r->angle()));
-        parent->setRotation(item);
+        parent->setRotationType(item);
     } else if (const auto* r = dynamic_cast<const RotationZ*>(rotation)) {
         auto* item = new ZRotationItem();
         item->setAngle(Units::rad2deg(r->angle()));
-        parent->setRotation(item);
+        parent->setRotationType(item);
     } else if (const auto* r = dynamic_cast<const RotationEuler*>(rotation)) {
         auto* item = new EulerRotationItem();
         item->setAlpha(Units::rad2deg(r->alpha()));
         item->setBeta(Units::rad2deg(r->beta()));
         item->setGamma(Units::rad2deg(r->gamma()));
-        parent->setRotation(item);
+        parent->setRotationType(item);
     }
 }
 
diff --git a/GUI/Model/Model/ParameterTreeUtils.cpp b/GUI/Model/Model/ParameterTreeUtils.cpp
index 61a31398867ebab551e282007cb01fc72ed69786..ca2c0dae05b00a12a13484f06b2d2bc68640be92 100644
--- a/GUI/Model/Model/ParameterTreeUtils.cpp
+++ b/GUI/Model/Model/ParameterTreeUtils.cpp
@@ -254,7 +254,7 @@ ParameterLabelItem* ParameterTreeBuilder::addParticle(ParameterLabelItem* parent
     addRotation(label, p);
 
     if (const auto* particle = dynamic_cast<const ParticleItem*>(p)) {
-        auto* formFactor = particle->formfactor();
+        auto* formFactor = particle->formfactorItem();
         auto* ffLabel = addLabel<FormFactorItemCatalog>(label, "Formfactor", formFactor);
         for (auto& d : formFactor->geometryProperties())
             addParameterItem(ffLabel, d);
@@ -286,7 +286,7 @@ ParameterLabelItem* ParameterTreeBuilder::addParticle(ParameterLabelItem* parent
 void ParameterTreeBuilder::addLattice(ParameterLabelItem* parentLabel,
                                       const Interference2DAbstractLatticeItem* itf)
 {
-    auto* lattice = itf->latticeType().currentItem();
+    auto* lattice = itf->latticeTypeItem();
     auto* label = addLabel<Lattice2DItemCatalog>(parentLabel, "Lattice", lattice);
     for (auto& d : lattice->geometryValues(!itf->xiIntegration()))
         addParameterItem(label, d);
@@ -350,7 +350,7 @@ void ParameterTreeBuilder::addBeamDistribution(ParameterLabelItem* parentLabel,
                                                BeamDistributionItem* distributionItem,
                                                const QString& label, bool withMean)
 {
-    auto* distribution = distributionItem->distribution();
+    auto* distribution = distributionItem->distributionItem();
     if (auto* dn = dynamic_cast<DistributionNoneItem*>(distribution)) {
         if (withMean)
             addParameterItem(parentLabel, dn->mean(), label);
@@ -368,7 +368,7 @@ void ParameterTreeBuilder::addDetector(ParameterLabelItem* parentLabel, Detector
 {
     const auto addResolutionFunction = [=](ParameterLabelItem* detLabel) {
         if (auto* r = dynamic_cast<ResolutionFunction2DGaussianItem*>(
-                detector->resolutionFunctionSelection().currentItem())) {
+                detector->resolutionFunction().currentItem())) {
             auto* label = new ParameterLabelItem("Resolution (Gaussian)", detLabel);
             addParameterItem(label, r->sigmaX());
             addParameterItem(label, r->sigmaY());
diff --git a/GUI/Model/Sample/InterferenceItems.cpp b/GUI/Model/Sample/InterferenceItems.cpp
index 1dee93a69eeb18531157fef6c558887472a940e0..817b17edf50ad4d63acf6176dc4a00b74f5e1df2 100644
--- a/GUI/Model/Sample/InterferenceItems.cpp
+++ b/GUI/Model/Sample/InterferenceItems.cpp
@@ -88,7 +88,7 @@ Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(bool xiInte
     : m_xiIntegration(xiIntegration)
 {
     m_latticeType.init("Lattice type", "");
-    m_latticeType.set(new HexagonalLattice2DItem());
+    m_latticeType.setCurrentItem(new HexagonalLattice2DItem());
 }
 
 // --------------------------------------------------------------------------------------------- //
@@ -101,7 +101,7 @@ Interference2DLatticeItem::Interference2DLatticeItem()
 
 std::unique_ptr<IInterference> Interference2DLatticeItem::createInterference() const
 {
-    Lattice2DItem* latticeItem = latticeType().currentItem();
+    Lattice2DItem* latticeItem = latticeTypeItem();
     std::unique_ptr<Interference2DLattice> result(
         new Interference2DLattice(*latticeItem->createLattice()));
 
@@ -138,7 +138,7 @@ Interference2DParacrystalItem::Interference2DParacrystalItem()
 
 std::unique_ptr<IInterference> Interference2DParacrystalItem::createInterference() const
 {
-    Lattice2DItem* latticeItem = latticeType().currentItem();
+    Lattice2DItem* latticeItem = latticeTypeItem();
 
     std::unique_ptr<Interference2DParacrystal> result(
         new Interference2DParacrystal(*latticeItem->createLattice(), 0, 0, 0));
@@ -173,7 +173,7 @@ InterferenceFinite2DLatticeItem::InterferenceFinite2DLatticeItem()
 
 std::unique_ptr<IInterference> InterferenceFinite2DLatticeItem::createInterference() const
 {
-    Lattice2DItem* latticeItem = latticeType().currentItem();
+    Lattice2DItem* latticeItem = latticeTypeItem();
     auto result = std::make_unique<InterferenceFinite2DLattice>(*latticeItem->createLattice(),
                                                                 m_domainSize1, m_domainSize2);
 
diff --git a/GUI/Model/Sample/InterferenceItems.h b/GUI/Model/Sample/InterferenceItems.h
index ca9f8100f04dc066a928141843f28025941235bc..97cd2306ff521e2ef81e941f4b164e8726c1257e 100644
--- a/GUI/Model/Sample/InterferenceItems.h
+++ b/GUI/Model/Sample/InterferenceItems.h
@@ -59,8 +59,8 @@ public:
     const DoubleProperty& rotationAngle() const { return m_rotationAngle; }
     void setRotationAngle(double v) { m_rotationAngle.setValue(v); }
 
-    void setDecayFunction(Profile1DItem* p) { m_decayFunction.set(p); }
-    SelectionDescriptor<Profile1DItem*> decayFunction() const { return m_decayFunction; }
+    SelectionProperty<Profile1DItemCatalog>& decayFunction() { return m_decayFunction; }
+    void setDecayFunctionType(Profile1DItem* p) { m_decayFunction.setCurrentItem(p); }
 
 private:
     DoubleProperty m_length;
@@ -72,11 +72,12 @@ private:
 
 class Interference2DAbstractLatticeItem : public InterferenceItem {
 public:
-    SelectionDescriptor<Lattice2DItem*> latticeType() const { return m_latticeType; }
-    void setLatticeType(Lattice2DItem* p) { m_latticeType.set(p); }
+    Lattice2DItem* latticeTypeItem() const { return m_latticeType.currentItem(); }
+    SelectionProperty<Lattice2DItemCatalog>& latticeType() { return m_latticeType; }
+    void setLatticeType(Lattice2DItem* p) { m_latticeType.setCurrentItem(p); }
 
     bool xiIntegration() const { return m_xiIntegration; }
-    void setXiIntegration(bool xiIntegration) { m_xiIntegration = xiIntegration; }
+    void setXiIntegration(bool b) { m_xiIntegration = b; }
 
 protected:
     explicit Interference2DAbstractLatticeItem(bool xiIntegration);
@@ -93,8 +94,8 @@ public:
     std::unique_ptr<IInterference> createInterference() const override;
     void serialize(Streamer& s) override;
 
-    void setDecayFunctionType(Profile2DItem* p) { m_decayFunction.set(p); }
-    SelectionDescriptor<Profile2DItem*> decayFunction() const { return m_decayFunction; }
+    SelectionProperty<Profile2DItemCatalog>& decayFunction() { return m_decayFunction; }
+    void setDecayFunctionType(Profile2DItem* p) { m_decayFunction.setCurrentItem(p); }
 
 protected:
     SelectionProperty<Profile2DItemCatalog> m_decayFunction;
@@ -120,11 +121,11 @@ public:
     const DoubleProperty& domainSize2() const { return m_domainSize2; }
     void setDomainSize2(double size) { m_domainSize2.setValue(size); }
 
-    SelectionDescriptor<Profile2DItem*> probabilityDistribution1() const { return m_pdf1; }
-    void setPDF1Type(Profile2DItem* p) { m_pdf1.set(p); }
+    SelectionProperty<Profile2DItemCatalog>& probabilityDistribution1() { return m_pdf1; }
+    void setPDF1Type(Profile2DItem* p) { m_pdf1.setCurrentItem(p); }
 
-    SelectionDescriptor<Profile2DItem*> probabilityDistribution2() const { return m_pdf2; }
-    void setPDF2Type(Profile2DItem* p) { m_pdf2.set(p); }
+    SelectionProperty<Profile2DItemCatalog>& probabilityDistribution2() { return m_pdf2; }
+    void setPDF2Type(Profile2DItem* p) { m_pdf2.setCurrentItem(p); }
 
 private:
     DoubleProperty m_dampingLength;
@@ -198,8 +199,8 @@ public:
     const DoubleProperty& kappa() const { return m_kappa; }
     void setKappa(double v) { m_kappa.setValue(v); }
 
-    SelectionDescriptor<Profile1DItem*> probabilityDistribution() const { return m_pdf; }
-    void setPDFType(Profile1DItem* p) { m_pdf.set(p); }
+    SelectionProperty<Profile1DItemCatalog>& probabilityDistribution() { return m_pdf; }
+    void setPDFType(Profile1DItem* p) { m_pdf.setCurrentItem(p); }
 
 private:
     DoubleProperty m_peakDistance;
diff --git a/GUI/Model/Sample/ItemWithParticles.cpp b/GUI/Model/Sample/ItemWithParticles.cpp
index c6b5478f0d98500a094d54db710df49838057a9d..ef81e55f85f0a39f25b76a10537eb107889982b4 100644
--- a/GUI/Model/Sample/ItemWithParticles.cpp
+++ b/GUI/Model/Sample/ItemWithParticles.cpp
@@ -30,7 +30,7 @@ ItemWithParticles::ItemWithParticles(const QString& abundanceTooltip,
 
 std::unique_ptr<IRotation> ItemWithParticles::createRotation() const
 {
-    if (!m_rotation.get())
+    if (!m_rotation.currentItem())
         return {};
     const auto matrix = m_rotation->rotation();
     return std::unique_ptr<IRotation>(IRotation::createRotation(matrix));
diff --git a/GUI/Model/Sample/ItemWithParticles.h b/GUI/Model/Sample/ItemWithParticles.h
index 9c13d727b985324e9c7a892f4208ebe5e3ebdb71..58070e652ccff96248a2ec25699ff8a0955805e5 100644
--- a/GUI/Model/Sample/ItemWithParticles.h
+++ b/GUI/Model/Sample/ItemWithParticles.h
@@ -37,11 +37,10 @@ public:
     const VectorProperty& position() const { return m_position; }
     void setPosition(const R3& position) { m_position.setR3(position); }
 
-    //! Returns selection descriptor for rotation methods.
-    SelectionDescriptor<RotationItem*> rotation() { return m_rotation; }
+    SelectionProperty<RotationItemCatalog>& rotation() { return m_rotation; }
 
     //! nullptr is allowed and sets to "no rotation"
-    void setRotation(RotationItem* p) { m_rotation.set(p); }
+    void setRotationType(RotationItem* p) { m_rotation.setCurrentItem(p); }
 
     //! nullptr only if "no rotation". Can contain identity!
     std::unique_ptr<IRotation> createRotation() const;
diff --git a/GUI/Model/Sample/LayerItem.cpp b/GUI/Model/Sample/LayerItem.cpp
index d04f9b498c6afc2d66e458be47f3c0ee78907171..1f0de3235599e2d73f36fad93f642911932ba0fa 100644
--- a/GUI/Model/Sample/LayerItem.cpp
+++ b/GUI/Model/Sample/LayerItem.cpp
@@ -92,19 +92,14 @@ QVector<ItemWithParticles*> LayerItem::itemsWithParticles() const
     return result;
 }
 
-SelectionDescriptor<RoughnessItem*> LayerItem::roughness()
-{
-    return m_roughness;
-}
-
 void LayerItem::setBasicRoughness()
 {
-    m_roughness.set(new BasicRoughnessItem);
+    m_roughness.setCurrentItem(new BasicRoughnessItem);
 }
 
 void LayerItem::clearRoughness()
 {
-    m_roughness.set(nullptr);
+    m_roughness.setCurrentItem(nullptr);
 }
 
 QVector<ParticleLayoutItem*> LayerItem::layouts() const
diff --git a/GUI/Model/Sample/LayerItem.h b/GUI/Model/Sample/LayerItem.h
index c08481de9edbf250d06114593488e249d2a30e15..02cea0a10692c08d8c0292e4944ce8525d1b84e9 100644
--- a/GUI/Model/Sample/LayerItem.h
+++ b/GUI/Model/Sample/LayerItem.h
@@ -41,7 +41,7 @@ public:
     const DoubleProperty& thickness() const { return m_thickness; }
     void setThickness(double v) { m_thickness.setValue(v); }
 
-    SelectionDescriptor<RoughnessItem*> roughness();
+    SelectionProperty<RoughnessItemCatalog>& roughness() { return m_roughness; }
     void setBasicRoughness();
     void clearRoughness();
 
diff --git a/GUI/Model/Sample/MesocrystalItem.cpp b/GUI/Model/Sample/MesocrystalItem.cpp
index ebac4d5e0b349d08e7b52a79544dd256b39dfd6c..b2fef110af0f7ea88fea2f9b2cc8e125c2bce822 100644
--- a/GUI/Model/Sample/MesocrystalItem.cpp
+++ b/GUI/Model/Sample/MesocrystalItem.cpp
@@ -109,16 +109,16 @@ Lattice3D MesocrystalItem::getLattice() const
 
 std::unique_ptr<IParticle> MesocrystalItem::getBasis() const
 {
-    if (auto* p = dynamic_cast<ParticleItem*>(m_basisParticle.get()))
+    if (auto* p = dynamic_cast<ParticleItem*>(m_basisParticle.currentItem()))
         return p->createParticle();
 
-    if (auto* p = dynamic_cast<CoreAndShellItem*>(m_basisParticle.get()))
+    if (auto* p = dynamic_cast<CoreAndShellItem*>(m_basisParticle.currentItem()))
         return p->createCoreAndShell();
 
-    if (auto* p = dynamic_cast<CompoundItem*>(m_basisParticle.get()))
+    if (auto* p = dynamic_cast<CompoundItem*>(m_basisParticle.currentItem()))
         return p->createCompound();
 
-    if (auto* p = dynamic_cast<MesocrystalItem*>(m_basisParticle.get()))
+    if (auto* p = dynamic_cast<MesocrystalItem*>(m_basisParticle.currentItem()))
         return p->createMesocrystal();
 
     return {};
@@ -129,17 +129,6 @@ std::unique_ptr<IFormFactor> MesocrystalItem::getOuterShape() const
     return m_outerShape->createFormFactor();
 }
 
-ItemWithParticles* MesocrystalItem::basisParticle() const
-{
-    return m_basisParticle.get();
-}
-
-void MesocrystalItem::setBasis(ItemWithParticles* basis)
-{
-    m_basisParticle.set(basis);
-}
-
-
 QVector<ItemWithParticles*> MesocrystalItem::containedItemsWithParticles() const
 {
     QVector<ItemWithParticles*> result;
diff --git a/GUI/Model/Sample/MesocrystalItem.h b/GUI/Model/Sample/MesocrystalItem.h
index 44cc2096e75deaed637bc885e620f731cf9cb95c..34e4b204a36909a272c4eb8e0ce7a38732d68b6d 100644
--- a/GUI/Model/Sample/MesocrystalItem.h
+++ b/GUI/Model/Sample/MesocrystalItem.h
@@ -43,11 +43,11 @@ public:
     template <typename T>
     T* setOuterShapeType();
 
-    SelectionDescriptor<FormFactorItem*> outerShape() const { return m_outerShape; }
-    void setOuterShape(FormFactorItem* p) { m_outerShape.set(p); }
+    SelectionProperty<FormFactorItemCatalog>& outerShape() { return m_outerShape; }
+    void setOuterShape(FormFactorItem* p) { m_outerShape.setCurrentItem(p); }
 
-    ItemWithParticles* basisParticle() const;
-    void setBasis(ItemWithParticles* basis);
+    ItemWithParticles* basisParticle() const { return m_basisParticle.currentItem(); }
+    void setBasis(ItemWithParticles* basis) { m_basisParticle.setCurrentItem(basis); }
 
     VectorProperty& vectorA() { return m_vectorA; }
     const VectorProperty& vectorA() const { return m_vectorA; }
diff --git a/GUI/Model/Sample/ParticleItem.cpp b/GUI/Model/Sample/ParticleItem.cpp
index f515e3fceb7a6f34804473ad12c132b4fcde34cb..664425be92263e1ba19046766159d688a1048206 100644
--- a/GUI/Model/Sample/ParticleItem.cpp
+++ b/GUI/Model/Sample/ParticleItem.cpp
@@ -46,7 +46,7 @@ ParticleItem::ParticleItem(const MaterialItems* materials)
     , ItemWithParticles(abundance_tooltip, position_tooltip)
 {
     m_formFactor.init("Form Factor", "");
-    m_formFactor.set(new CylinderItem());
+    m_formFactor.setCurrentItem(new CylinderItem());
 }
 
 void ParticleItem::serialize(Streamer& s)
@@ -74,12 +74,12 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const
 
 void ParticleItem::setFormFactor(FormFactorItem* p)
 {
-    m_formFactor.set(p);
+    m_formFactor.setCurrentItem(p);
 }
 
-FormFactorItem* ParticleItem::formfactor() const
+FormFactorItem* ParticleItem::formfactorItem() const
 {
-    return m_formFactor.get();
+    return m_formFactor.currentItem();
 }
 
 QVector<ItemWithParticles*> ParticleItem::containedItemsWithParticles() const
diff --git a/GUI/Model/Sample/ParticleItem.h b/GUI/Model/Sample/ParticleItem.h
index 91428e50f7c3c688e3eef91b69e9a0705790b167..e635ae73b6fed04661aec8025acc3b636e99a56c 100644
--- a/GUI/Model/Sample/ParticleItem.h
+++ b/GUI/Model/Sample/ParticleItem.h
@@ -34,7 +34,7 @@ public:
     template <typename T>
     T* setFormFactorType();
     void setFormFactor(FormFactorItem* p);
-    FormFactorItem* formfactor() const;
+    FormFactorItem* formfactorItem() const;
     QVector<ItemWithParticles*> containedItemsWithParticles() const override;
 
 private:
diff --git a/GUI/Model/Sample/ParticleLayoutItem.cpp b/GUI/Model/Sample/ParticleLayoutItem.cpp
index cdb3124223d1e9e79501715db30effd8b19c86e0..3ba10c2b5ad1bbd39b3c256f53b49b07498486c9 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.cpp
+++ b/GUI/Model/Sample/ParticleLayoutItem.cpp
@@ -48,11 +48,11 @@ double ParticleLayoutItem::totalDensityValue() const
     if (!totalDensityIsDefinedByInterference())
         return m_ownDensity.value();
 
-    ASSERT(m_interference.get());
+    ASSERT(m_interference.currentItem());
 
     if (const auto* interLatticeItem =
-            dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get())) {
-        Lattice2DItem* latticeItem = interLatticeItem->latticeType().currentItem();
+            dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.currentItem())) {
+        Lattice2DItem* latticeItem = interLatticeItem->latticeTypeItem();
         try {
             const double area = latticeItem->unitCellArea();
             return area == 0.0 ? 0.0 : 1.0 / area;
@@ -62,7 +62,8 @@ double ParticleLayoutItem::totalDensityValue() const
         }
     }
 
-    if (const auto* hd = dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get()))
+    if (const auto* hd =
+            dynamic_cast<const InterferenceHardDiskItem*>(m_interference.currentItem()))
         return hd->density();
 
     ASSERT(false);
@@ -92,25 +93,15 @@ QVector<ItemWithParticles*> ParticleLayoutItem::containedItemsWithParticles() co
     return result;
 }
 
-SelectionDescriptor<InterferenceItem*> ParticleLayoutItem::interference() const
+const SelectionProperty<InterferenceItemCatalog>& ParticleLayoutItem::interference() const
 {
     return m_interference;
 }
 
-void ParticleLayoutItem::setInterference(InterferenceItem* interference)
-{
-    m_interference.set(interference);
-}
-
-void ParticleLayoutItem::removeInterference()
-{
-    m_interference.set(nullptr);
-}
-
 bool ParticleLayoutItem::totalDensityIsDefinedByInterference() const
 {
-    return dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get())
-           || dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get());
+    return dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.currentItem())
+           || dynamic_cast<const InterferenceHardDiskItem*>(m_interference.currentItem());
 }
 
 void ParticleLayoutItem::serialize(Streamer& s)
diff --git a/GUI/Model/Sample/ParticleLayoutItem.h b/GUI/Model/Sample/ParticleLayoutItem.h
index 6fffa7e58a489c3f416929b91f6b2aeceebf865b..4c3e6fd1b6a1ccdf93e517f6457ba1e3256082cc 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.h
+++ b/GUI/Model/Sample/ParticleLayoutItem.h
@@ -59,9 +59,10 @@ public:
     //! \sa particles()
     QVector<ItemWithParticles*> containedItemsWithParticles() const;
 
-    SelectionDescriptor<InterferenceItem*> interference() const;
-    void setInterference(InterferenceItem* interference);
-    void removeInterference();
+    SelectionProperty<InterferenceItemCatalog>& interference() { return m_interference; }
+    const SelectionProperty<InterferenceItemCatalog>& interference() const;
+    void setInterference(InterferenceItem* i) { m_interference.setCurrentItem(i); }
+    void removeInterference() { m_interference.setCurrentItem(nullptr); }
 
     //! Returns whether total density is defined by the currently selected interference.
     //!
diff --git a/GUI/Model/ToCore/SimulationToCore.cpp b/GUI/Model/ToCore/SimulationToCore.cpp
index 1ec1f0dbbfed63beb37e1eb8edffad2c53d703b4..330ecfb6ef0840f7793f99ae499dc975af9bfa46 100644
--- a/GUI/Model/ToCore/SimulationToCore.cpp
+++ b/GUI/Model/ToCore/SimulationToCore.cpp
@@ -76,7 +76,7 @@ std::unique_ptr<ScanResolution> createScanResolution(const BeamDistributionItem*
     if (!item)
         return nullptr;
 
-    const auto* distr_item = dynamic_cast<const SymmetricResolutionItem*>(item->distribution());
+    const auto* distr_item = dynamic_cast<const SymmetricResolutionItem*>(item->distributionItem());
     if (!distr_item)
         return nullptr;
 
@@ -130,7 +130,7 @@ SpecularSimulation* createSpecularSimulation(std::unique_ptr<MultiLayer> sample,
 {
     auto* beam_item = item->beamItem();
     auto* const axis_item = beam_item->inclinationAxis();
-    auto* const footprint_item = beam_item->footprint();
+    auto* const footprint_item = beam_item->footprint().currentItem();
 
     AlphaScan scan(beam_item->wavelength(), *axis_item->createAxis(Units::deg));
     scan.setFootprintFactor(footprint_item->createFootprint().get());
diff --git a/GUI/View/Common/DoubleLineEdit.h b/GUI/View/Common/DoubleLineEdit.h
index d41b2fa07118d742d8b79237ed5d469492c11f0c..2b77ef94d36ac63f516db988650aa197fe3f59eb 100644
--- a/GUI/View/Common/DoubleLineEdit.h
+++ b/GUI/View/Common/DoubleLineEdit.h
@@ -38,7 +38,7 @@ public:
 signals:
     //! Emitted whenever the value changes.
     //!
-    //! newBaseValue is in the unit of the valueDescriptor.
+    //! newBaseValue is in the unit of the valueProperty.
     void baseValueChanged(double newBaseValue);
 
 private slots:
diff --git a/GUI/View/Common/DoubleSpinBox.h b/GUI/View/Common/DoubleSpinBox.h
index 5a298fde617b89d94cf126349eaad2df5da25b65..ee036ebefa72f98d99714f82e2583ffe7c981cf4 100644
--- a/GUI/View/Common/DoubleSpinBox.h
+++ b/GUI/View/Common/DoubleSpinBox.h
@@ -47,7 +47,7 @@ public:
     //! Returns the unit of the contained DoubleProperty.
     //!
     //! If the unit is defined as a string, this method returns Unit::other. To get the string, use
-    //! valueDescriptor().unit
+    //! valueProperty().unit
     Unit baseUnit() const;
 
     //! Update the shown value to the one contained in the value descriptor.
@@ -58,7 +58,7 @@ public:
 signals:
     //! Emitted whenever the value changes.
     //!
-    //! newBaseValue is in the unit of the valueDescriptor.
+    //! newBaseValue is in the unit of the valueProperty.
     void baseValueChanged(double newBaseValue);
 
 protected:
diff --git a/GUI/View/Instrument/DetectorEditor.cpp b/GUI/View/Instrument/DetectorEditor.cpp
index 7ecdb9455ddd2f23307a331cf6a837b3701962fa..1b3eec2bdc37a2ccdb3cd370a28ac4364bd64537 100644
--- a/GUI/View/Instrument/DetectorEditor.cpp
+++ b/GUI/View/Instrument/DetectorEditor.cpp
@@ -31,7 +31,7 @@ DetectorEditor::DetectorEditor(QWidget* parent, Instrument2DItem* instrument)
     m_formLayout = new QFormLayout(this);
 
     auto* detectorTypeCombo =
-        GUI::Util::createComboBoxFromDescriptor(instrument->detectorSelection(), [=](int) {
+        GUI::Util::createComboBoxFromProperty(instrument->detector(), [=](int) {
             createDetectorWidgets();
             emit dataChanged();
         });
@@ -47,7 +47,7 @@ void DetectorEditor::createDetectorWidgets()
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
-    auto* detectorItem = m_instrument->detectorSelection().currentItem();
+    auto* detectorItem = m_instrument->detectorItem();
     if (auto* rect = dynamic_cast<RectangularDetectorItem*>(detectorItem)) {
         auto* editor = new RectangularDetectorEditor(this, rect);
         m_formLayout->addRow(editor);
diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Instrument/DistributionEditor.cpp
index 9c9116d32b3c8bceb1fc6167c3f3a4d9df8f2716..c9e866bb995786888a5834f1e69c6d876560336f 100644
--- a/GUI/View/Instrument/DistributionEditor.cpp
+++ b/GUI/View/Instrument/DistributionEditor.cpp
@@ -45,11 +45,10 @@ DistributionSelector::DistributionSelector(std::optional<MeanConfig> mean_config
     m_formLayout = new QFormLayout(this);
     m_formLayout->setContentsMargins(0, 0, 0, 0);
 
-    m_distributionCombo =
-        GUI::Util::createComboBoxFromDescriptor(item->distributionSelection(), [=](int) {
-            createDistributionWidgets();
-            emit distributionChanged();
-        });
+    m_distributionCombo = GUI::Util::createComboBoxFromProperty(item->distribution(), [=](int) {
+        createDistributionWidgets();
+        emit distributionChanged();
+    });
     m_formLayout->addRow("Distribution:", m_distributionCombo);
 
     createDistributionWidgets();
@@ -60,12 +59,12 @@ void DistributionSelector::createDistributionWidgets()
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
-    if (auto* cosine = dynamic_cast<DistributionCosineItem*>(m_item->distribution())) {
+    if (auto* cosine = dynamic_cast<DistributionCosineItem*>(m_item->distributionItem())) {
         createMeanSpinBox(cosine->mean());
         createSpinBox(cosine->sigma());
         createNumSamplesSpinBox(cosine);
         createSpinBox(cosine->sigmaFactor());
-    } else if (auto* gate = dynamic_cast<DistributionGateItem*>(m_item->distribution())) {
+    } else if (auto* gate = dynamic_cast<DistributionGateItem*>(m_item->distributionItem())) {
         auto* minSpinbox = createSpinBox(gate->minimum());
         auto* maxSpinbox = createSpinBox(gate->maximum());
         connect(minSpinbox, &DoubleSpinBox::baseValueChanged, [=](double d) {
@@ -81,24 +80,26 @@ void DistributionSelector::createDistributionWidgets()
             }
         });
         createNumSamplesSpinBox(gate);
-    } else if (auto* gauss = dynamic_cast<DistributionGaussianItem*>(m_item->distribution())) {
+    } else if (auto* gauss = dynamic_cast<DistributionGaussianItem*>(m_item->distributionItem())) {
         createMeanSpinBox(gauss->mean());
         createSpinBox(gauss->standardDeviation());
         createNumSamplesSpinBox(gauss);
         createSpinBox(gauss->sigmaFactor());
-    } else if (auto* logNormal = dynamic_cast<DistributionLogNormalItem*>(m_item->distribution())) {
+    } else if (auto* logNormal =
+                   dynamic_cast<DistributionLogNormalItem*>(m_item->distributionItem())) {
         createSpinBox(logNormal->median());
         createSpinBox(logNormal->scaleParameter());
         createNumSamplesSpinBox(logNormal);
         createSpinBox(logNormal->sigmaFactor());
-    } else if (auto* lorentz = dynamic_cast<DistributionLorentzItem*>(m_item->distribution())) {
+    } else if (auto* lorentz = dynamic_cast<DistributionLorentzItem*>(m_item->distributionItem())) {
         createMeanSpinBox(lorentz->mean());
         createSpinBox(lorentz->hwhm());
         createNumSamplesSpinBox(lorentz);
         createSpinBox(lorentz->sigmaFactor());
-    } else if (auto* none = dynamic_cast<DistributionNoneItem*>(m_item->distribution())) {
+    } else if (auto* none = dynamic_cast<DistributionNoneItem*>(m_item->distributionItem())) {
         createMeanSpinBox(none->mean());
-    } else if (auto* trapezoid = dynamic_cast<DistributionTrapezoidItem*>(m_item->distribution())) {
+    } else if (auto* trapezoid =
+                   dynamic_cast<DistributionTrapezoidItem*>(m_item->distributionItem())) {
         createSpinBox(trapezoid->center());
         createSpinBox(trapezoid->leftWidth());
         createSpinBox(trapezoid->middleWidth());
@@ -156,7 +157,7 @@ GUI::ID::Distributions DistributionSelector::distributions() const
 void DistributionSelector::refresh()
 {
     QSignalBlocker b(m_distributionCombo);
-    m_distributionCombo->setCurrentIndex(m_item->distributionSelection().currentIndex());
+    m_distributionCombo->setCurrentIndex(m_item->distribution().currentIndex());
     createDistributionWidgets();
 }
 
@@ -200,7 +201,7 @@ void DistributionEditor::updateData()
 
 void DistributionEditor::updatePlot()
 {
-    auto* d = m_selector->item()->distribution();
+    auto* d = m_selector->item()->distributionItem();
     m_plot->setVisible(!dynamic_cast<const DistributionNoneItem*>(d));
     m_plot->setDistItem(d);
     m_plot->plotItem();
diff --git a/GUI/View/Instrument/EnvironmentEditor.cpp b/GUI/View/Instrument/EnvironmentEditor.cpp
index 514bfac3e490f246f6c94d3541f6242be3518ec8..a17f986e49b1d315be3c4b4350ffa2e98ef70ef4 100644
--- a/GUI/View/Instrument/EnvironmentEditor.cpp
+++ b/GUI/View/Instrument/EnvironmentEditor.cpp
@@ -29,7 +29,7 @@ EnvironmentEditor::EnvironmentEditor(QWidget* parent, InstrumentItem* instrument
     m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
 
     auto* backgroundTypeCombo =
-        GUI::Util::createComboBoxFromDescriptor(instrument->backgroundSelection(), [=](int) {
+        GUI::Util::createComboBoxFromProperty(instrument->background(), [=](int) {
             createBackgroundWidgets();
             emit dataChanged();
         });
@@ -44,7 +44,7 @@ void EnvironmentEditor::createBackgroundWidgets()
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
-    auto* backgroundItem = m_instrument->backgroundSelection().currentItem();
+    auto* backgroundItem = m_instrument->backgroundItem();
     if (auto* p = dynamic_cast<ConstantBackgroundItem*>(backgroundItem)) {
         auto* spinbox = new DoubleSpinBox(p->backgroundValue());
         spinbox->setSingleStep(0.01);
diff --git a/GUI/View/Instrument/FootprintCorrectionEditor.cpp b/GUI/View/Instrument/FootprintCorrectionEditor.cpp
index 349034b05294d73dfeac22703e6e834f804179c1..859d2210a37ccb48aa368a01a9f4c28dd0737190 100644
--- a/GUI/View/Instrument/FootprintCorrectionEditor.cpp
+++ b/GUI/View/Instrument/FootprintCorrectionEditor.cpp
@@ -28,7 +28,7 @@ FootprintCorrectionEditor::FootprintCorrectionEditor(QWidget* parent, SpecularBe
     setProperty("subgroup", true); // for stylesheet addressing
     m_formLayout = new QFormLayout(this);
     m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
-    auto* typeCombo = GUI::Util::createComboBoxFromDescriptor(item->footprintSelection(), [=](int) {
+    auto* typeCombo = GUI::Util::createComboBoxFromProperty(item->footprint(), [=](int) {
         createFootprintWidgets();
         emit dataChanged();
     });
@@ -44,7 +44,7 @@ void FootprintCorrectionEditor::createFootprintWidgets()
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
-    auto* footprintItem = m_item->footprintSelection().currentItem();
+    auto* footprintItem = m_item->footprint().currentItem();
     if (auto* square = dynamic_cast<FootprintSquareItem*>(footprintItem)) {
         auto* spinbox = new DoubleSpinBox(square->squareFootprintValue());
         spinbox->setSingleStep(0.01);
diff --git a/GUI/View/Instrument/InclinationAnglesEditor.cpp b/GUI/View/Instrument/InclinationAnglesEditor.cpp
index 50c837995cdecb18e8f559ad5661fa409ef8f02d..972d464298bccd68d245a5b16e757cd74dc84362 100644
--- a/GUI/View/Instrument/InclinationAnglesEditor.cpp
+++ b/GUI/View/Instrument/InclinationAnglesEditor.cpp
@@ -96,7 +96,7 @@ void InclinationAnglesEditor::onAxisTypeSelected(int index)
 
 void InclinationAnglesEditor::updatePlot()
 {
-    auto* d = m_selector->item()->distribution();
+    auto* d = m_selector->item()->distributionItem();
     m_plot->setVisible(!dynamic_cast<const DistributionNoneItem*>(d));
     m_plot->setDistItem(d);
     m_plot->plotItem();
diff --git a/GUI/View/Instrument/ResolutionFunctionEditor.cpp b/GUI/View/Instrument/ResolutionFunctionEditor.cpp
index 9d6f18ef2c084657f75a64ca3ba77c9bafef1aea..4518aac1a543ad1fc55a28aaaa042e75d5b650bb 100644
--- a/GUI/View/Instrument/ResolutionFunctionEditor.cpp
+++ b/GUI/View/Instrument/ResolutionFunctionEditor.cpp
@@ -31,11 +31,10 @@ ResolutionFunctionEditor::ResolutionFunctionEditor(Unit unit, QWidget* parent, D
     m_formLayout = new QFormLayout(this);
     m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
 
-    auto* typeCombo =
-        GUI::Util::createComboBoxFromDescriptor(item->resolutionFunctionSelection(), [=](int) {
-            createResolutionWidgets();
-            emit dataChanged();
-        });
+    auto* typeCombo = GUI::Util::createComboBoxFromProperty(item->resolutionFunction(), [=](int) {
+        createResolutionWidgets();
+        emit dataChanged();
+    });
     m_formLayout->addRow("Type:", typeCombo);
 
     GroupBoxCollapser::installIntoGroupBox(this);
@@ -48,7 +47,7 @@ void ResolutionFunctionEditor::createResolutionWidgets()
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
-    auto* resFunction = m_item->resolutionFunctionSelection().currentItem();
+    auto* resFunction = m_item->resolutionFunction().currentItem();
     if (auto* p = dynamic_cast<ResolutionFunction2DGaussianItem*>(resFunction)) {
         auto* sigmaXSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaX());
         auto* sigmaYSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaY());
diff --git a/GUI/View/SampleDesigner/CoreAndShellForm.cpp b/GUI/View/SampleDesigner/CoreAndShellForm.cpp
index 6c38086b00cada5260040275707e1146a27f5477..1943c2c1f6cecff7b34ef10a386fcca4d336b118 100644
--- a/GUI/View/SampleDesigner/CoreAndShellForm.cpp
+++ b/GUI/View/SampleDesigner/CoreAndShellForm.cpp
@@ -69,7 +69,7 @@ CoreAndShellForm::CoreAndShellForm(QWidget* parent, CoreAndShellItem* item,
         core.layouter = std::make_unique<FormLayouter>(coreParticleGroup, ec);
 
         core.formfactorCombo = createFormFactorCombo(
-            coreParticleGroup, item->core() != nullptr ? item->core()->formfactor() : nullptr);
+            coreParticleGroup, item->core() != nullptr ? item->core()->formfactorItem() : nullptr);
         connect(core.formfactorCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
                 &CoreAndShellForm::onCoreComboChanged);
         core.layouter->addRow("Form factor:", core.formfactorCombo);
@@ -92,7 +92,8 @@ CoreAndShellForm::CoreAndShellForm(QWidget* parent, CoreAndShellItem* item,
         shellParticleGroup->setObjectName("Particle");
         shell.layouter = std::make_unique<FormLayouter>(shellParticleGroup, ec);
         shell.formfactorCombo = createFormFactorCombo(
-            shellParticleGroup, item->shell() != nullptr ? item->shell()->formfactor() : nullptr);
+            shellParticleGroup,
+            item->shell() != nullptr ? item->shell()->formfactorItem() : nullptr);
         connect(shell.formfactorCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
                 &CoreAndShellForm::onShellComboChanged);
         shell.layouter->addRow("Form factor:", shell.formfactorCombo);
@@ -158,10 +159,11 @@ void CoreAndShellForm::createCoreWidgets()
     QString groupTitle = "Core";
 
     if (ParticleItem* particle = m_item->core()) {
-        const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactor());
+        const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactorItem());
         groupTitle += " (" + formfactor + ")";
 
-        core.layouter->addGroupOfValues("Geometry", particle->formfactor()->geometryProperties());
+        core.layouter->addGroupOfValues("Geometry",
+                                        particle->formfactorItem()->geometryProperties());
         core.layouter->addVector(particle->position(), false);
         core.layouter->addSelection(particle->rotation());
         // no abundance since this is handled in CoreShell itself!
@@ -175,10 +177,11 @@ void CoreAndShellForm::createShellWidgets()
     QString groupTitle = "Shell";
 
     if (ParticleItem* particle = m_item->shell()) {
-        const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactor());
+        const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactorItem());
         groupTitle += " (" + formfactor + ")";
 
-        shell.layouter->addGroupOfValues("Geometry", particle->formfactor()->geometryProperties());
+        shell.layouter->addGroupOfValues("Geometry",
+                                         particle->formfactorItem()->geometryProperties());
         shell.layouter->addSelection(particle->rotation());
         // no position vector - not allowed in CoreShell
         // no abundance since this is handled in CoreShell itself!
diff --git a/GUI/View/SampleDesigner/FormLayouter.h b/GUI/View/SampleDesigner/FormLayouter.h
index 2d19425d1222915bd54a63dd63bba6eac82cb305..d98fb41e2ea3a970bcda1ccc06e9104689f6df97 100644
--- a/GUI/View/SampleDesigner/FormLayouter.h
+++ b/GUI/View/SampleDesigner/FormLayouter.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H
 #define BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H
 
-#include "GUI/Model/Descriptor/SelectionDescriptor.h"
+#include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/View/SampleDesigner/SelectionContainerForm.h"
 #include <QFormLayout>
 
@@ -84,7 +84,7 @@ public:
     //! For more details, see SelectionContainerForm.
     //! Returns the newly added row.
     template <typename T>
-    int addSelection(const SelectionDescriptor<T>& d);
+    int addSelection(SelectionProperty<T>& d);
 
     //! Adds a row with a bold printed label and a DoubleSpinBox.
     //!
@@ -115,7 +115,7 @@ public:
     //! Same functionality as addValue(), please read there.
     void insertValue(int row, DoubleProperty& d, std::function<void(double)> onValueChange);
 
-    //! Adds a row with a bold printed label and a set of DoubleDescriptors.
+    //! Adds a row with a bold printed label and a set of DoubleProperties.
     //!
     //! The label describes the set of the DoubleProperties and is located in the first column of
     //! the layout. The DoubleSpinBoxes for each DoubleProperty are created as children of a newly
@@ -160,10 +160,10 @@ private:
 };
 
 template <typename T>
-int FormLayouter::addSelection(const SelectionDescriptor<T>& d)
+int FormLayouter::addSelection(SelectionProperty<T>& d)
 {
     auto* w = new SelectionContainerForm(m_formLayout->parentWidget(), d, m_ec);
-    return addRow(d.label, w);
+    return addRow(d.label(), w);
 }
 
 template <typename T>
diff --git a/GUI/View/SampleDesigner/InterferenceForm.cpp b/GUI/View/SampleDesigner/InterferenceForm.cpp
index a31b2d5f94bf2bc5194faaf850a80afddd29cb2f..4c8bb49cf3dd1b632623e48c320d8b1565d37e80 100644
--- a/GUI/View/SampleDesigner/InterferenceForm.cpp
+++ b/GUI/View/SampleDesigner/InterferenceForm.cpp
@@ -38,8 +38,8 @@ InterferenceForm::InterferenceForm(QWidget* parent, ParticleLayoutItem* layoutIt
 
     m_interferenceTypeCombo = new QComboBox(this);
     WheelEventEater::install(m_interferenceTypeCombo);
-    auto d = layoutItem->interference();
-    m_interferenceTypeCombo->addItems(d.options);
+    const auto& d = layoutItem->interference();
+    m_interferenceTypeCombo->addItems(d.options());
     m_interferenceTypeCombo->setCurrentIndex(d.currentIndex());
     m_interferenceTypeCombo->setMaxVisibleItems(m_interferenceTypeCombo->count());
     m_interferenceTypeCombo->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
@@ -101,7 +101,7 @@ void InterferenceForm::createInterferenceWidgets()
     } else if (auto* itf = dynamic_cast<Interference2DLatticeItem*>(interference)) {
         layouter.addValue(itf->positionVariance());
         auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
-        layouter.addRow(itf->latticeType().label, w);
+        layouter.addRow(itf->latticeType().label(), w);
         layouter.addSelection(itf->decayFunction());
     } else if (auto* itf = dynamic_cast<InterferenceFinite2DLatticeItem*>(interference)) {
         layouter.addValue(itf->positionVariance());
@@ -123,14 +123,14 @@ void InterferenceForm::createInterferenceWidgets()
                                                     "Domain size 2 in number of unit cells"));
 
         auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
-        layouter.addRow(itf->latticeType().label, w);
+        layouter.addRow(itf->latticeType().label(), w);
     } else if (auto* itf = dynamic_cast<Interference2DParacrystalItem*>(interference)) {
         layouter.addValue(itf->positionVariance());
         layouter.addValue(itf->dampingLength());
         layouter.addValue(itf->domainSize1());
         layouter.addValue(itf->domainSize2());
         auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
-        layouter.addRow(itf->latticeType().label, w);
+        layouter.addRow(itf->latticeType().label(), w);
         layouter.addSelection(itf->probabilityDistribution1());
         layouter.addSelection(itf->probabilityDistribution2());
     }
diff --git a/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp b/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp
index 6055e19267e59715898c4e526665ea85739451e3..277988b7e6b011a258f335427fde8572553f7703 100644
--- a/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp
+++ b/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp
@@ -30,13 +30,13 @@ LatticeTypeSelectionForm::LatticeTypeSelectionForm(
 void LatticeTypeSelectionForm::createContent()
 {
     auto* currentLatticeType = m_interferenceItem->latticeType().currentItem();
-    const auto valueDescriptors = currentLatticeType->geometryValues(false);
-    const bool vertical = valueDescriptors.size() > 2;
+    const auto valueProperties = currentLatticeType->geometryValues(false);
+    const bool vertical = valueProperties.size() > 2;
 
     const auto onValueChange = [this](double newValue, DoubleProperty& d) {
         m_ec->setDensityRelatedValue(m_interferenceItem, newValue, d);
     };
-    LayerEditorUtils::addMultiPropertyToGrid(m_gridLayout, 1, valueDescriptors, onValueChange,
+    LayerEditorUtils::addMultiPropertyToGrid(m_gridLayout, 1, valueProperties, onValueChange,
                                              vertical, false);
 
     m_integrateOverXiCheckBox = new QCheckBox("Integrate over Xi", this);
diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.cpp b/GUI/View/SampleDesigner/LayerEditorUtils.cpp
index a332500f84d0100bf6435e5342fd47e7ab08ca72..37c355fcd301bb8056f71a25cab03ad5b6bc97a7 100644
--- a/GUI/View/SampleDesigner/LayerEditorUtils.cpp
+++ b/GUI/View/SampleDesigner/LayerEditorUtils.cpp
@@ -65,7 +65,7 @@ void LayerEditorUtils::updateLabelUnit(QLabel* label)
 }
 
 void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                                              const DoublePropertyRefs& valueDescriptors,
+                                              const DoublePropertyRefs& valueProperties,
                                               SampleEditorController* ec, bool vertically,
                                               bool addSpacer)
 {
@@ -73,17 +73,17 @@ void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int fir
         ec->setDouble(newValue, d);
     };
 
-    addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, setNewValue, vertically,
+    addMultiPropertyToGrid(m_gridLayout, firstCol, valueProperties, setNewValue, vertically,
                            addSpacer);
 }
 
 void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                                              const DoublePropertyRefs& valueDescriptors,
+                                              const DoublePropertyRefs& valueProperties,
                                               function<void(double, DoubleProperty&)> setNewValue,
                                               bool vertically, bool addSpacer)
 {
     int col = firstCol;
-    for (DoubleProperty& d : valueDescriptors) {
+    for (DoubleProperty& d : valueProperties) {
         DoubleSpinBox* editor;
         if (d.label() == "Angle")
             editor = new DoubleSpinBox(d, false, 1, 1.0);
@@ -114,11 +114,11 @@ void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int fir
 }
 
 void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                                              const DoublePropertyRefs& valueDescriptors,
+                                              const DoublePropertyRefs& valueProperties,
                                               SampleEditorController* ec, bool addSpacer)
 {
-    addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, ec,
-                           valueDescriptors.size() > 1, addSpacer);
+    addMultiPropertyToGrid(m_gridLayout, firstCol, valueProperties, ec, valueProperties.size() > 1,
+                           addSpacer);
 }
 
 void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v,
@@ -150,31 +150,35 @@ DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RotationItem* item)
 {
     if (!item)
         return {};
-
     return item->rotationProperties();
 }
 
 DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(Profile2DItem* item)
 {
+    if (!item)
+        return {};
     return item->profileProperties();
 }
 
 DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(Profile1DItem* item)
 {
+    if (!item)
+        return {};
     return item->profileProperties();
 }
 
 DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(FormFactorItem* item)
 {
+    if (!item)
+        return {};
     return item->geometryProperties();
 }
 
-DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RoughnessItem* r)
+DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RoughnessItem* item)
 {
-    if (!r)
+    if (!item)
         return {};
-
-    return r->roughnessProperties();
+    return item->roughnessProperties();
 }
 
 QWidget* LayerEditorUtils::createWidgetForItemWithParticles(QWidget* parentWidget,
diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.h b/GUI/View/SampleDesigner/LayerEditorUtils.h
index eadd0180559fddba8db2c032099c1bd99d8faf2c..9e7c88cddc6f8190e0e0d1271147ad342ba204aa 100644
--- a/GUI/View/SampleDesigner/LayerEditorUtils.h
+++ b/GUI/View/SampleDesigner/LayerEditorUtils.h
@@ -43,28 +43,28 @@ namespace LayerEditorUtils {
 void updateLabelUnit(QLabel* label);
 void updateLabelUnit(QLabel* label, DoubleSpinBox* editor);
 
-//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to
+//! Create DoubleSpinBoxes for the DoubleProperties and connect them to
 //! SampleEditorController::setDouble()
 void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                            const DoublePropertyRefs& valueDescriptors, SampleEditorController* ec,
+                            const DoublePropertyRefs& valueProperties, SampleEditorController* ec,
                             bool vertically, bool addSpacer);
 
-//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to the given setNewValue()
+//! Create DoubleSpinBoxes for the DoubleProperties and connect them to the given setNewValue()
 void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                            const DoublePropertyRefs& valueDescriptors,
+                            const DoublePropertyRefs& valueProperties,
                             std::function<void(double, DoubleProperty&)> setNewValue,
                             bool vertically, bool addSpacer);
 
 void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
-                            const DoublePropertyRefs& valueDescriptors, SampleEditorController* ec,
+                            const DoublePropertyRefs& valueProperties, SampleEditorController* ec,
                             bool addSpacer);
 
-//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to
+//! Create DoubleSpinBoxes for the DoubleProperties and connect them to
 //! SampleEditorController::setDouble()
 void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v,
                      SampleEditorController* ec, bool vertically, bool addSpacer);
 
-//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to the given setNewValue()
+//! Create DoubleSpinBoxes for the DoubleProperties and connect them to the given setNewValue()
 void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v,
                      std::function<void(double, DoubleProperty&)> setNewValue, bool vertically,
                      bool addSpacer);
diff --git a/GUI/View/SampleDesigner/MesocrystalForm.cpp b/GUI/View/SampleDesigner/MesocrystalForm.cpp
index 2e35b64ccafc699788dfc3811d586b56e8b39684..8a13ad160f69b8b689274d05e12927a9142a3330 100644
--- a/GUI/View/SampleDesigner/MesocrystalForm.cpp
+++ b/GUI/View/SampleDesigner/MesocrystalForm.cpp
@@ -72,7 +72,7 @@ QComboBox* MesocrystalForm::createBasisCombo(QWidget* parent, ItemWithParticles*
         const auto ui = FormFactorItemCatalog::uiInfo(type);
         combo->addItem(QIcon(ui.iconPath), ui.menuEntry, static_cast<uint32_t>(type));
         if (auto* p = dynamic_cast<ParticleItem*>(current))
-            if (FormFactorItemCatalog::type(p->formfactor()) == type)
+            if (FormFactorItemCatalog::type(p->formfactorItem()) == type)
                 currentData = static_cast<uint32_t>(type);
     }
     for (auto type : ItemWithParticlesCatalog::assemblyTypes()) {
diff --git a/GUI/View/SampleDesigner/ParticleForm.cpp b/GUI/View/SampleDesigner/ParticleForm.cpp
index 5a12035217fc51173af451d2adac89a9db7214b1..7a726cb20353e9b9a068e3e43a5e9e37f6786c40 100644
--- a/GUI/View/SampleDesigner/ParticleForm.cpp
+++ b/GUI/View/SampleDesigner/ParticleForm.cpp
@@ -26,12 +26,12 @@ ParticleForm::ParticleForm(QWidget* parent, ParticleItem* particleItem, bool all
                            SampleEditorController* ec, bool allowRemove)
     : QGroupBox(parent)
 {
-    const QString formfactor = FormFactorItemCatalog::menuEntry(particleItem->formfactor());
+    const QString formfactor = FormFactorItemCatalog::menuEntry(particleItem->formfactorItem());
     setTitle("Particle (" + formfactor + ")");
 
     FormLayouter layouter(this, ec);
     layouter.addRow("Material", new MaterialInplaceForm(this, particleItem, ec));
-    layouter.addGroupOfValues("Geometry", particleItem->formfactor()->geometryProperties());
+    layouter.addGroupOfValues("Geometry", particleItem->formfactorItem()->geometryProperties());
     layouter.addVector(particleItem->position(), false);
     layouter.addSelection(particleItem->rotation());
     if (allowAbundance)
diff --git a/GUI/View/SampleDesigner/SampleEditorController.cpp b/GUI/View/SampleDesigner/SampleEditorController.cpp
index 4edca089d2a80914f63e2292e130494d2d6a7a26..e35898f0cd773cd8cb86491ba713944b825b1573 100644
--- a/GUI/View/SampleDesigner/SampleEditorController.cpp
+++ b/GUI/View/SampleDesigner/SampleEditorController.cpp
@@ -340,7 +340,7 @@ void SampleEditorController::setDoubleFromUndo(double newValue, const QString& p
 }
 
 void SampleEditorController::setCurrentIndex(AbstractSelectionContainerForm* widget, int index,
-                                             const AbstractSelectionDescriptor& d)
+                                             AbstractSelectionProperty& d)
 {
     d.setCurrentIndex(index);
     widget->createContent();
@@ -400,7 +400,7 @@ void SampleEditorController::setDensityRelatedValue(InterferenceItem* interferen
     // -- notify the containing particle layout UI about changed value
     ASSERT(m_sampleForm);
     for (auto* c : m_sampleForm->findChildren<ParticleLayoutForm*>())
-        if (c->layoutItem()->interference() == interferenceItem) {
+        if (c->layoutItem()->interference().currentItem() == interferenceItem) {
             c->updateDensityValue();
             break;
         }
diff --git a/GUI/View/SampleDesigner/SampleEditorController.h b/GUI/View/SampleDesigner/SampleEditorController.h
index c73e5cc195367339add35264ff1441e94e51f623..ac243dcc9ef0271bcd5f996c52718821490aa6b9 100644
--- a/GUI/View/SampleDesigner/SampleEditorController.h
+++ b/GUI/View/SampleDesigner/SampleEditorController.h
@@ -20,7 +20,7 @@
 #include <QUndoStack>
 
 class AbstractSelectionContainerForm;
-class AbstractSelectionDescriptor;
+class AbstractSelectionProperty;
 class CompoundItem;
 class CoreAndShellForm;
 class DoubleProperty;
@@ -94,7 +94,7 @@ public:
     void setDoubleFromUndo(double newValue, const QString& path);
 
     void setCurrentIndex(AbstractSelectionContainerForm* widget, int index,
-                         const AbstractSelectionDescriptor& d);
+                         AbstractSelectionProperty& d);
 
     void selectMaterial(ItemWithMaterial* item, const QString& newMaterialIdentifier);
     void setMaterialValue(ItemWithMaterial* item, double newValue, DoubleProperty& d);
diff --git a/GUI/View/SampleDesigner/SelectionContainerForm.h b/GUI/View/SampleDesigner/SelectionContainerForm.h
index e4e8af4cacf2de6e309c5d98b8507333d3f63e1b..dba2787d85aff4c73b195510317a9400a94ad3b7 100644
--- a/GUI/View/SampleDesigner/SelectionContainerForm.h
+++ b/GUI/View/SampleDesigner/SelectionContainerForm.h
@@ -39,7 +39,7 @@ protected:
     }
 
     template <typename T>
-    void initUI(const SelectionDescriptor<T>& d)
+    void initUI(SelectionProperty<T>& d)
     {
         m_gridLayout = new QGridLayout(this);
         m_gridLayout->setContentsMargins(0, 0, 0, 0);
@@ -47,12 +47,12 @@ protected:
 
         m_combo = new QComboBox;
         WheelEventEater::install(m_combo);
-        m_combo->addItems(d.options);
+        m_combo->addItems(d.options());
         m_combo->setCurrentIndex(d.currentIndex());
         m_combo->setMaxVisibleItems(m_combo->count());
 
         QObject::connect(m_combo, QOverload<int>::of(&QComboBox::currentIndexChanged),
-                         [=](int current) {
+                         [this, &d](int current) {
                              clear();
                              m_ec->setCurrentIndex(this, current, d);
                          });
@@ -62,7 +62,7 @@ protected:
     }
 
 private:
-    //! Remove all descriptors from the layout
+    //! Remove all properties from the layout
     void clear()
     {
         auto* layoutItemOfComboBox = m_gridLayout->itemAtPosition(1, 0);
@@ -77,22 +77,23 @@ protected:
     SampleEditorController* m_ec;
 };
 
-//! A widget to contain a selection, defined by a SelectionDescriptor.
+//! A widget to contain a selection, defined by a SelectionProperty.
 //!
 //! This SelectionContainerForm is limited to contain the selection combo box and a list of double
-//! values represented by DoubleDescriptors. The list of DoubleDescriptors is queried by calling
-//! LayerEditorUtils::doubleDescriptorsOfItem(). To have the correct DoubleDescriptors on this form,
+//! values represented by DoubleProperties. The list of DoubleProperties is queried by calling
+//! LayerEditorUtils::doublePropertiesOfItem(). To have the correct DoubleProperties on this form,
 //! you may have to overload this method according to your class and your needs. The overload will
-//! expect the template type you defined for SelectionDescriptor.
+//! expect the template type you defined for SelectionProperty.
 //!
 //! Example:
-//! SelectionDescriptor<RotationItem*>  => LayerEditorUtils::doubleDescriptorsOfItem(RotationItem*)
+//! SelectionProperty<RotationItemCatalog>  =>
+//! LayerEditorUtils::doublePropertiesOfItem(RotationItem*)
 //!
-//! The connection from selection combo -> SelectionDescriptor is made via
+//! The connection from selection combo -> SelectionProperty is made via
 //! SampleEditorController::setCurrentIndex(), where a command can be used for undo purposes.
 //!
-//! For each DoubleDescriptor, a unit-aware DoubleSpinBox is created. The connection from each
-//! spinbox to the DoubleDescriptor is made via SampleEditorController::setDouble(), where a command
+//! For each DoubleProperty, a unit-aware DoubleSpinBox is created. The connection from each
+//! spinbox to the DoubleProperty is made via SampleEditorController::setDouble(), where a command
 //! can be used for undo purposes.
 //!
 //! If a more complex selection shall be realized (e.g. with
@@ -100,17 +101,10 @@ protected:
 class SelectionContainerForm : public AbstractSelectionContainerForm {
 public:
     template <typename T>
-    SelectionContainerForm(QWidget* parent, const SelectionDescriptor<T>& d,
-                           SampleEditorController* ec)
+    SelectionContainerForm(QWidget* parent, SelectionProperty<T>& d, SampleEditorController* ec)
         : AbstractSelectionContainerForm(parent, ec)
     {
-        if (d.currentItem != nullptr)
-            currentValues = [=] {
-                return LayerEditorUtils::doublePropertiesOfItem(d.currentItem());
-            };
-        else
-            currentValues = [] { return DoublePropertyRefs(); };
-
+        currentValues = [&d] { return LayerEditorUtils::doublePropertiesOfItem(d.currentItem()); };
         initUI(d);
     }
 
diff --git a/GUI/View/Tool/WidgetUtils.cpp b/GUI/View/Tool/WidgetUtils.cpp
index 2888eeb8b3d2f589a56ff7142febae33664b73af..a1152172f6a617312dc14d2fe1a5298991888dbe 100644
--- a/GUI/View/Tool/WidgetUtils.cpp
+++ b/GUI/View/Tool/WidgetUtils.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/View/Tool/WidgetUtils.h"
+#include "GUI/Util/ComboProperty.h"
 #include "GUI/View/Common/DoubleSpinBox.h"
 #include "GUI/View/Common/ScientificSpinBox.h"
 #include "GUI/View/Tool/EditUtil.h"
diff --git a/GUI/View/Tool/WidgetUtils.h b/GUI/View/Tool/WidgetUtils.h
index 5e514927a9056ac18a15f78cb6c8266538229a3c..8c1b8b6c7b99fe5860a3a4e41c6898671f4bb545 100644
--- a/GUI/View/Tool/WidgetUtils.h
+++ b/GUI/View/Tool/WidgetUtils.h
@@ -16,12 +16,13 @@
 #define BORNAGAIN_GUI_VIEW_TOOL_WIDGETUTILS_H
 
 #include "Fit/Param/RealLimits.h"
-#include "GUI/Model/Descriptor/SelectionDescriptor.h"
+#include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Support/Type/Unit.h"
 #include "GUI/View/Common/CustomEventFilters.h"
 #include <QComboBox>
 #include <variant>
 
+class ComboProperty;
 class QSpinBox;
 class QCheckBox;
 class DoubleSpinBox;
@@ -51,7 +52,7 @@ QComboBox* createSafeComboBox(std::function<ComboProperty()> comboFunction,
                               QList<std::function<void()>>* updaters = nullptr,
                               QString tooltip = "");
 
-//! Create a combo box with the information found in a selection descriptor.
+//! Create a combo box with the information found in a selection property.
 //!
 //! The combo will be filled with the available options and will get the found tooltip.
 //! The current index will be set according to the current index in the selection.
@@ -59,38 +60,29 @@ QComboBox* createSafeComboBox(std::function<ComboProperty()> comboFunction,
 //! would be dangerous if the combo is on a scrollable form - unintended and unnoticed changes would
 //! take place when just scrolling through the form.
 //!
-//! Changes in the combobox will be notified to the SelectionDescriptor already. The additional (and
+//! Changes in the combobox will be notified to the SelectionProperty already. The additional (and
 //! optional) slot can be used to be notified about an already executed change.
 //!
-//! The combo can be updated from outside using "updaters" list.
-//!
 template <typename T>
-QComboBox* createComboBoxFromDescriptor(SelectionDescriptor<T> d,
-                                        std::function<void(int)> slot = nullptr,
-                                        QList<std::function<void()>>* updaters = nullptr,
-                                        bool isScrollable = false)
+QComboBox* createComboBoxFromProperty(SelectionProperty<T>& d,
+                                      std::function<void(int)> slot = nullptr,
+                                      bool isScrollable = false)
 {
     QComboBox* combo = new QComboBox;
-    combo->addItems(d.options);
-    combo->setMaxCount(d.options.size());
-    combo->setToolTip(d.tooltip);
+    combo->addItems(d.options());
+    combo->setMaxCount(d.options().size());
+    combo->setToolTip(d.tooltip());
     combo->setCurrentIndex(d.currentIndex());
 
     if (!isScrollable)
         WheelEventEater::install(combo);
 
-    QObject::connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
+    QObject::connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), [&d, slot](int index) {
         d.setCurrentIndex(index);
         if (slot)
             slot(index);
     });
 
-    if (updaters)
-        (*updaters) << [=]() {
-            QSignalBlocker b(combo);
-            combo->setCurrentIndex(d.currentIndex());
-        };
-
     return combo;
 }
 
diff --git a/Tests/Unit/GUI/TestDetectorItems.cpp b/Tests/Unit/GUI/TestDetectorItems.cpp
index 7904bb781c57c91a412a89ed084f05fa62518e22..2f22a28f1f1ccd850dbf391ddba68bcc37f988ca 100644
--- a/Tests/Unit/GUI/TestDetectorItems.cpp
+++ b/Tests/Unit/GUI/TestDetectorItems.cpp
@@ -41,7 +41,7 @@ TEST_F(TestDetectorItems, resolutionFunctionUnit)
     detector.setResolutionFunctionType<ResolutionFunctionNoneItem>();
     detector.setResolutionFunctionType<ResolutionFunction2DGaussianItem>();
     auto* p = dynamic_cast<ResolutionFunction2DGaussianItem*>(
-        detector.resolutionFunctionSelection().currentItem());
+        detector.resolutionFunction().currentItem());
     EXPECT_NE(p, nullptr);
     EXPECT_EQ(asString(p->sigmaX().unit()), "mm");
     EXPECT_EQ(asString(p->sigmaY().unit()), "mm");
@@ -50,7 +50,7 @@ TEST_F(TestDetectorItems, resolutionFunctionUnit)
     sphericalDetector.setResolutionFunctionType<ResolutionFunctionNoneItem>();
     sphericalDetector.setResolutionFunctionType<ResolutionFunction2DGaussianItem>();
     p = dynamic_cast<ResolutionFunction2DGaussianItem*>(
-        sphericalDetector.resolutionFunctionSelection().currentItem());
+        sphericalDetector.resolutionFunction().currentItem());
     EXPECT_NE(p, nullptr);
     EXPECT_EQ(asString(p->sigmaX().unit()), unitAsString(Unit::degree));
     EXPECT_EQ(asString(p->sigmaY().unit()), unitAsString(Unit::degree));