diff --git a/GUI/Model/Descriptor/SelectionProperty.h b/GUI/Model/Descriptor/SelectionProperty.h
index 84e7674c50dbc9f77398d796758eaa3622f36fb8..5bb9eda7dcba77eba1d90482bfb46bb03984d5fb 100644
--- a/GUI/Model/Descriptor/SelectionProperty.h
+++ b/GUI/Model/Descriptor/SelectionProperty.h
@@ -45,10 +45,10 @@
 //!
 //! This means especially that this class is **not** relying on the existence of a related catalog
 //! class - a catalog helps but is not mandatory.
-//!
+//!Catalog
 //! \sa SelectionDescriptor
 //!
-template <typename T>
+template <typename T, typename Catalog>
 class SelectionProperty {
 public:
     ~SelectionProperty() { delete m_p; }
@@ -58,12 +58,12 @@ public:
     //! The current selection will be initialized with the first type in the catalog types. The
     //! optional arguments are the arguments which may be necessary for the creation method in the
     //! catalog.
-    template <typename Catalog, typename... ArgsForCreation>
+    template <typename... ArgsForCreation>
     void init(const QString& label, const QString& tooltip, const QString& persistentTag,
               ArgsForCreation... argsForCreation)
     {
         m_persistentTag = persistentTag;
-        initDescriptor<Catalog>(label, tooltip, Catalog::types(), argsForCreation...);
+        initDescriptor(label, tooltip, Catalog::types(), argsForCreation...);
         m_descriptor.setCurrentIndex(0);
     }
 
@@ -78,7 +78,6 @@ public:
     //! old one (if present; can be null). This is intended to maybe copy values from the old to the
     //! new selection. The old item also can be ignored, always according to the current
     //! needs.
-    template <typename Catalog>
     void initWithInitializer(const QString& label, const QString& tooltip,
                              const QString& persistentTag,
                              std::function<void(T newItem, const T oldItem)> initializer)
@@ -86,7 +85,7 @@ public:
         m_initializer = initializer;
         m_persistentTag = persistentTag;
 
-        initDescriptor<Catalog>(label, tooltip, Catalog::types());
+        initDescriptor(label, tooltip, Catalog::types());
         m_descriptor.setCurrentIndex(0);
     }
 
@@ -103,7 +102,6 @@ public:
     //! old one (if present; can be null). This is intended to maybe copy values from the old to the
     //! new selection. The old item also can be ignored, always according to the current
     //! needs.
-    template <typename Catalog>
     void initWithInitializer(const QString& label, const QString& tooltip,
                              const QString& persistentTag,
                              const QVector<typename Catalog::Type>& types,
@@ -112,7 +110,7 @@ public:
         m_initializer = initializer;
         m_persistentTag = persistentTag;
 
-        initDescriptor<Catalog>(label, tooltip, types);
+        initDescriptor(label, tooltip, types);
         m_descriptor.setCurrentIndex(0);
     }
 
@@ -150,7 +148,7 @@ public:
 
 
 private:
-    template <typename Catalog, typename... ArgsForCreation>
+    template <typename... ArgsForCreation>
     void initDescriptor(const QString& label, const QString& tooltip,
                         const QVector<typename Catalog::Type>& types,
                         ArgsForCreation... argsForCreation)
@@ -190,7 +188,7 @@ namespace Serialize {
 //! Serializes an item from a catalog.
 //! Passes optional arguments to the constructor.
 template <typename Catalog, typename... ArgsForCreation>
-void rwSelected(Streamer& s, SelectionProperty<typename Catalog::CatalogedType*>& d,
+void rwSelected(Streamer& s, SelectionProperty<typename Catalog::CatalogedType*, Catalog>& d,
                 ArgsForCreation... argsForCreation);
 
 } // namespace Serialize
@@ -200,7 +198,7 @@ void rwSelected(Streamer& s, SelectionProperty<typename Catalog::CatalogedType*>
 //  ************************************************************************************************
 
 template <typename Catalog, typename... ArgsForCreation>
-void Serialize::rwSelected(Streamer& s, SelectionProperty<typename Catalog::CatalogedType*>& d,
+void Serialize::rwSelected(Streamer& s, SelectionProperty<typename Catalog::CatalogedType*, Catalog>& d,
                            ArgsForCreation... argsForCreation)
 {
     if (QXmlStreamWriter* w = s.xmlWriter()) {
diff --git a/GUI/Model/Device/BeamAngleItems.cpp b/GUI/Model/Device/BeamAngleItems.cpp
index cee11ae7ed05d2bd625747f7c6be14245452fd65..469cfc6435dd347620d12a0c7dae7ade7b8e6b37 100644
--- a/GUI/Model/Device/BeamAngleItems.cpp
+++ b/GUI/Model/Device/BeamAngleItems.cpp
@@ -14,12 +14,11 @@
 
 #include "GUI/Model/Device/BeamAngleItems.h"
 #include "Base/Const/Units.h"
-#include "GUI/Model/CatDevice/DistributionItemCatalog.h"
 #include "GUI/Support/XML/Serialize.h"
 
 BeamAzimuthalAngleItem::BeamAzimuthalAngleItem()
 {
-    m_distribution.initWithInitializer<DistributionItemCatalog>(
+    m_distribution.initWithInitializer(
         "Distribution", "", "distribution", DistributionItemCatalog::types(), initDistribution);
 }
 
@@ -66,7 +65,7 @@ double BeamAzimuthalAngleItem::scaleFactor() const
 
 BeamInclinationAngleItem::BeamInclinationAngleItem()
 {
-    m_distribution.initWithInitializer<DistributionItemCatalog>(
+    m_distribution.initWithInitializer(
         "Distribution", "", "distribution", DistributionItemCatalog::types(), initDistribution);
 }
 
diff --git a/GUI/Model/Device/BeamDistributionItem.cpp b/GUI/Model/Device/BeamDistributionItem.cpp
index e0a02c223f872e6ca870805d3c6a46cd1f9a39f9..61bc6342e68c084ea72bdfa6fdeb2aabcac7f7c0 100644
--- a/GUI/Model/Device/BeamDistributionItem.cpp
+++ b/GUI/Model/Device/BeamDistributionItem.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Device/BeamDistributionItem.h"
-#include "GUI/Model/CatDevice/DistributionItemCatalog.h"
 #include "GUI/Support/XML/Serialize.h"
 #include "Param/Distrib/Distributions.h"
 
diff --git a/GUI/Model/Device/BeamDistributionItem.h b/GUI/Model/Device/BeamDistributionItem.h
index eaff4730dcabd0ae5b72f58cecbde1eb90def785..38ffae77b7b404ac3798728475a8f6ff6c6a8c11 100644
--- a/GUI/Model/Device/BeamDistributionItem.h
+++ b/GUI/Model/Device/BeamDistributionItem.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODEL_DEVICE_BEAMDISTRIBUTIONITEM_H
 #define BORNAGAIN_GUI_MODEL_DEVICE_BEAMDISTRIBUTIONITEM_H
 
+#include "GUI/Model/CatDevice/DistributionItemCatalog.h"
 #include "GUI/Model/Descriptor/DistributionItems.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "Param/Distrib/ParameterDistribution.h"
@@ -45,7 +46,7 @@ public:
 protected:
     virtual std::unique_ptr<IDistribution1D> createDistribution1D() const;
 
-    SelectionProperty<DistributionItem*> m_distribution;
+    SelectionProperty<DistributionItem*, DistributionItemCatalog> m_distribution;
 };
 
 template <typename T>
diff --git a/GUI/Model/Device/BeamItems.cpp b/GUI/Model/Device/BeamItems.cpp
index 0b308384ff4612e7a84061a096d5d9912b9b2bef..c5ecd34ecc0fb794575cd4b783e5523603e25d8b 100644
--- a/GUI/Model/Device/BeamItems.cpp
+++ b/GUI/Model/Device/BeamItems.cpp
@@ -16,7 +16,6 @@
 #include "Base/Axis/IAxis.h"
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
-#include "GUI/Model/CatDevice/FootprintItemCatalog.h"
 #include "GUI/Model/Device/BeamAngleItems.h"
 #include "GUI/Model/Device/BeamWavelengthItem.h"
 #include "GUI/Model/Device/FootprintItems.h"
@@ -136,7 +135,7 @@ SpecularBeamItem::SpecularBeamItem(const InstrumentItem* owningInstrument)
     m_inclinationAngleItem.reset(new SpecularBeamInclinationItem(owningInstrument));
     initWavelength<SpecularBeamWavelengthItem>();
 
-    m_footprint.init<FootprintItemCatalog>("Type", "Footprint type", "footprint");
+    m_footprint.init("Type", "Footprint type", "footprint");
 }
 
 void SpecularBeamItem::serialize(Streamer& s)
diff --git a/GUI/Model/Device/BeamItems.h b/GUI/Model/Device/BeamItems.h
index c61a12bc4f18d524b223fe0d4d66af6f2b7ce58b..c3b5df7976d3edcb9c66a3777a660f44f082bb26 100644
--- a/GUI/Model/Device/BeamItems.h
+++ b/GUI/Model/Device/BeamItems.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H
 #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"
@@ -90,7 +91,7 @@ public:
     void updateWavelength();
 
 private:
-    SelectionProperty<FootprintItem*> m_footprint;
+    SelectionProperty<FootprintItem*, FootprintItemCatalog> m_footprint;
 };
 
 class GISASBeamItem : public BeamItem {
diff --git a/GUI/Model/Device/BeamWavelengthItem.cpp b/GUI/Model/Device/BeamWavelengthItem.cpp
index 658b7e305cd85d2d7ec681dec69d188d8a4af737..13d6c52ff94bfd73e16bc798e0ed938291f76a5e 100644
--- a/GUI/Model/Device/BeamWavelengthItem.cpp
+++ b/GUI/Model/Device/BeamWavelengthItem.cpp
@@ -47,7 +47,7 @@ BeamWavelengthItem::BeamWavelengthItem()
 
 BeamWavelengthItem::BeamWavelengthItem(bool onlySymmetricDistributions)
 {
-    m_distribution.initWithInitializer<DistributionItemCatalog>(
+    m_distribution.initWithInitializer(
         "Distribution", "", "distribution",
         onlySymmetricDistributions ? DistributionItemCatalog::symmetricTypes()
                                    : DistributionItemCatalog::types(),
diff --git a/GUI/Model/Device/DetectorItems.h b/GUI/Model/Device/DetectorItems.h
index a0d3a29c119cea42ca289ae13f8ba3a25af1c4ed..b58900175bb6f438f235c1652bc21c197dd02db2 100644
--- a/GUI/Model/Device/DetectorItems.h
+++ b/GUI/Model/Device/DetectorItems.h
@@ -17,6 +17,7 @@
 
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Device/MaskItems.h"
+#include "GUI/Model/CatDevice/ResolutionFunctionItemCatalog.h"
 #include "GUI/Model/Device/ResolutionFunctionItems.h"
 #include <heinz/Vectors3D.h>
 
@@ -66,7 +67,7 @@ protected:
 
 protected:
     MaskItems m_maskItems; //!< for creation of domain detector; only filled and relevant in jobs
-    SelectionProperty<ResolutionFunctionItem*> m_resolutionFunction;
+    SelectionProperty<ResolutionFunctionItem*, ResolutionFunctionItemCatalog> m_resolutionFunction;
 };
 
 template <typename T>
diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp
index bcf9554412191040aad200195cfa5ada071fa818..7d80ce77c71470eeb9468c610709b32c291e7ac8 100644
--- a/GUI/Model/Device/InstrumentItems.cpp
+++ b/GUI/Model/Device/InstrumentItems.cpp
@@ -20,8 +20,6 @@
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Detector/RectangularDetector.h"
 #include "Device/Detector/SphericalDetector.h"
-#include "GUI/Model/CatDevice/BackgroundItemCatalog.h"
-#include "GUI/Model/CatDevice/DetectorItemCatalog.h"
 #include "GUI/Model/CatDevice/InstrumentItemCatalog.h"
 #include "GUI/Model/Data/RealItem.h"
 #include "GUI/Model/Device/BackgroundItems.h"
@@ -85,7 +83,7 @@ InstrumentItem::InstrumentItem()
                         "polarization");
     m_analyzerDirection.init("Analyzer direction", "Direction of the polarization analysis",
                              Unit::unitless, "analyzerDirection");
-    m_backgroundItem.init<BackgroundItemCatalog>("Background", "", "background");
+    m_backgroundItem.init("Background", "", "background");
 }
 
 InstrumentItem* InstrumentItem::createCopy() const
@@ -352,7 +350,7 @@ const ICoordSystem* DepthProbeInstrumentItem::createCoordSystem() const
 Instrument2DItem::Instrument2DItem()
 {
     m_beamItem.reset(new GISASBeamItem());
-    m_detectorItem.init<DetectorItemCatalog>("Detector", "", "detector");
+    m_detectorItem.init("Detector", "", "detector");
 }
 
 void Instrument2DItem::serialize(Streamer& s)
diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h
index 8851c321c68f709cb63554233c6a99dfc89f8fb4..cfae9adc3310dcf89ec361c9cc04af0c8d861c56 100644
--- a/GUI/Model/Device/InstrumentItems.h
+++ b/GUI/Model/Device/InstrumentItems.h
@@ -15,12 +15,14 @@
 #ifndef BORNAGAIN_GUI_MODEL_DEVICE_INSTRUMENTITEMS_H
 #define BORNAGAIN_GUI_MODEL_DEVICE_INSTRUMENTITEMS_H
 
+#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"
-#include "GUI/Model/Device/BeamItems.h" // inheritance prevents forward declaration
+#include "GUI/Model/Device/BeamItems.h"
 #include "GUI/Model/Device/DetectorItems.h"
 #include <functional>
 #include <memory>
@@ -114,7 +116,7 @@ protected:
     QString m_name;
     QString m_description;
     bool m_withPolarizerAnalyzer;
-    SelectionProperty<BackgroundItem*> m_backgroundItem;
+    SelectionProperty<BackgroundItem*, BackgroundItemCatalog> m_backgroundItem;
     std::unique_ptr<BeamItem> m_beamItem;
 
     VectorProperty m_polarization;
@@ -188,7 +190,7 @@ public:
 protected:
     Instrument2DItem();
 
-    SelectionProperty<DetectorItem*> m_detectorItem;
+    SelectionProperty<DetectorItem*, DetectorItemCatalog> m_detectorItem;
 };
 
 
diff --git a/GUI/Model/Device/RectangularDetectorItem.cpp b/GUI/Model/Device/RectangularDetectorItem.cpp
index 7b423ed024b2de7e47e9f0a1e3f4b3b7d2bf3f52..054f034370f361470566ebaedea5e788169051b4 100644
--- a/GUI/Model/Device/RectangularDetectorItem.cpp
+++ b/GUI/Model/Device/RectangularDetectorItem.cpp
@@ -80,7 +80,7 @@ void initResolutionFunction(ResolutionFunctionItem* newFunc, const ResolutionFun
 
 RectangularDetectorItem::RectangularDetectorItem()
 {
-    m_resolutionFunction.initWithInitializer<ResolutionFunctionItemCatalog>(
+    m_resolutionFunction.initWithInitializer(
         "Resolution function", "Detector resolution function", "resolutionFunction",
         initResolutionFunction);
 
diff --git a/GUI/Model/Device/SpecularBeamInclinationItem.cpp b/GUI/Model/Device/SpecularBeamInclinationItem.cpp
index cdc46e774583ecfd7ed2b11d4d26cb9de27e6b82..d9e77cc388be17688fc14cf5e0f6730fb738ad68 100644
--- a/GUI/Model/Device/SpecularBeamInclinationItem.cpp
+++ b/GUI/Model/Device/SpecularBeamInclinationItem.cpp
@@ -66,7 +66,7 @@ SpecularBeamInclinationItem::SpecularBeamInclinationItem(const InstrumentItem* o
     : BeamDistributionItem()
     , m_owningInstrument(owningInstrument)
 {
-    m_distribution.initWithInitializer<DistributionItemCatalog>(
+    m_distribution.initWithInitializer(
         "Distribution", "", "distribution", DistributionItemCatalog::symmetricTypes(),
         initDistribution);
 
diff --git a/GUI/Model/Device/SphericalDetectorItem.cpp b/GUI/Model/Device/SphericalDetectorItem.cpp
index fecd05526f37da9a4579337cea5839da8613fb26..78a60c28bf1f7a00023ff1d83b389ff3058f30c3 100644
--- a/GUI/Model/Device/SphericalDetectorItem.cpp
+++ b/GUI/Model/Device/SphericalDetectorItem.cpp
@@ -15,7 +15,6 @@
 #include "GUI/Model/Device/SphericalDetectorItem.h"
 #include "Base/Const/Units.h"
 #include "Device/Detector/SphericalDetector.h"
-#include "GUI/Model/CatDevice/ResolutionFunctionItemCatalog.h"
 #include "GUI/Support/XML/Serialize.h"
 #include "ResolutionFunctionItems.h"
 
@@ -28,7 +27,7 @@ void initResolutionFunction(ResolutionFunctionItem* newFunc, const ResolutionFun
 
 SphericalDetectorItem::SphericalDetectorItem()
 {
-    m_resolutionFunction.initWithInitializer<ResolutionFunctionItemCatalog>(
+    m_resolutionFunction.initWithInitializer(
         "Resolution function", "Detector resolution function", "resolutionFunction",
         initResolutionFunction);
 
diff --git a/GUI/Model/Sample/InterferenceItems.cpp b/GUI/Model/Sample/InterferenceItems.cpp
index 04b45db401cb8b4e8fd58c8c28a36c64d97b663b..ef06223cf22930d0c0b9a30ddc5277bd516e4147 100644
--- a/GUI/Model/Sample/InterferenceItems.cpp
+++ b/GUI/Model/Sample/InterferenceItems.cpp
@@ -12,12 +12,8 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/Model/Sample/InterferenceItems.h"
 #include "Base/Const/Units.h"
-#include "GUI/Model/CatSample/Lattice2DItemCatalog.h"
-#include "GUI/Model/CatSample/ProfileItemCatalogs.h"
-#include "GUI/Model/Sample/Lattice2DItems.h"
-#include "GUI/Model/Sample/ProfileItems.h"
+#include "GUI/Model/Sample/InterferenceItems.h"
 #include "GUI/Support/XML/Serialize.h"
 #include "Sample/Aggregate/Interferences.h"
 
@@ -60,7 +56,7 @@ Interference1DLatticeItem::Interference1DLatticeItem()
     m_rotationAngle.init(
         "Xi", "Rotation of lattice with respect to x-axis of reference frame (beam direction)", 0.0,
         Unit::degree, "xi");
-    m_decayFunction.init<Profile1DItemCatalog>(
+    m_decayFunction.init(
         "Decay Function", "One-dimensional decay function (finite size effects)", "decay");
 }
 
@@ -87,7 +83,7 @@ void Interference1DLatticeItem::serialize(Streamer& s)
 Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(bool xiIntegration)
     : m_xiIntegration(xiIntegration)
 {
-    m_latticeType.init<Lattice2DItemCatalog>("Lattice type", "", "latticeType");
+    m_latticeType.init("Lattice type", "", "latticeType");
     m_latticeType.set(new HexagonalLattice2DItem());
 }
 
@@ -96,7 +92,7 @@ Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(bool xiInte
 Interference2DLatticeItem::Interference2DLatticeItem()
     : Interference2DAbstractLatticeItem(false)
 {
-    m_decayFunction.init<Profile2DItemCatalog>(
+    m_decayFunction.init(
         "Decay Function", "Two-dimensional decay function (finite size effects)", "decay");
 }
 
@@ -133,9 +129,9 @@ Interference2DParacrystalItem::Interference2DParacrystalItem()
                        20000.0, Unit::nanometer, "size1");
     m_domainSize2.init("Domain size 2", "Size of the coherent domain along the second basis vector",
                        20000.0, Unit::nanometer, "size2");
-    m_pdf1.init<Profile2DItemCatalog>(
+    m_pdf1.init(
         "PDF 1", "Probability distribution in first lattice direction", "pdf1");
-    m_pdf2.init<Profile2DItemCatalog>(
+    m_pdf2.init(
         "PDF 2", "Probability distribution in second lattice direction", "pdf2");
 }
 
@@ -234,7 +230,7 @@ InterferenceRadialParacrystalItem::InterferenceRadialParacrystalItem()
     m_kappa.init("SizeSpaceCoupling",
                  "Size spacing coupling parameter of the Size Spacing Correlation Approximation",
                  0.0, Unit::unitless, "kappa");
-    m_pdf.init<Profile1DItemCatalog>("PDF", "One-dimensional probability distribution", "pdf");
+    m_pdf.init("PDF", "One-dimensional probability distribution", "pdf");
 }
 
 std::unique_ptr<IInterference> InterferenceRadialParacrystalItem::createInterference() const
diff --git a/GUI/Model/Sample/InterferenceItems.h b/GUI/Model/Sample/InterferenceItems.h
index 85586a5c5119e263fc6397c243436de346b29e06..28b23c170144b07cb285f1eab96c10ddd29cf65f 100644
--- a/GUI/Model/Sample/InterferenceItems.h
+++ b/GUI/Model/Sample/InterferenceItems.h
@@ -15,6 +15,8 @@
 #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H
 #define BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H
 
+#include "GUI/Model/CatSample/Lattice2DItemCatalog.h"
+#include "GUI/Model/CatSample/ProfileItemCatalogs.h"
 #include "GUI/Model/Descriptor/DoubleProperty.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Sample/Lattice2DItems.h"
@@ -63,7 +65,7 @@ public:
 private:
     DoubleProperty m_length;
     DoubleProperty m_rotationAngle;
-    SelectionProperty<Profile1DItem*> m_decayFunction;
+    SelectionProperty<Profile1DItem*, Profile1DItemCatalog> m_decayFunction;
 };
 
 // ------------------------------------------------------------------------------------------------
@@ -80,7 +82,7 @@ protected:
     explicit Interference2DAbstractLatticeItem(bool xiIntegration);
 
     bool m_xiIntegration;
-    SelectionProperty<Lattice2DItem*> m_latticeType;
+    SelectionProperty<Lattice2DItem*, Lattice2DItemCatalog> m_latticeType;
 };
 
 // ------------------------------------------------------------------------------------------------
@@ -95,7 +97,7 @@ public:
     SelectionDescriptor<Profile2DItem*> decayFunction() const { return m_decayFunction; }
 
 protected:
-    SelectionProperty<Profile2DItem*> m_decayFunction;
+    SelectionProperty<Profile2DItem*, Profile2DItemCatalog> m_decayFunction;
 };
 
 // ------------------------------------------------------------------------------------------------
@@ -128,8 +130,8 @@ private:
     DoubleProperty m_dampingLength;
     DoubleProperty m_domainSize1;
     DoubleProperty m_domainSize2;
-    SelectionProperty<Profile2DItem*> m_pdf1;
-    SelectionProperty<Profile2DItem*> m_pdf2;
+    SelectionProperty<Profile2DItem*, Profile2DItemCatalog> m_pdf1;
+    SelectionProperty<Profile2DItem*, Profile2DItemCatalog> m_pdf2;
 };
 
 // ------------------------------------------------------------------------------------------------
@@ -204,7 +206,7 @@ private:
     DoubleProperty m_dampingLength;
     DoubleProperty m_domainSize;
     DoubleProperty m_kappa;
-    SelectionProperty<Profile1DItem*> m_pdf;
+    SelectionProperty<Profile1DItem*, Profile1DItemCatalog> m_pdf;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H
diff --git a/GUI/Model/Sample/ItemWithParticles.cpp b/GUI/Model/Sample/ItemWithParticles.cpp
index 4d09d2470b88ed4256fc53623fe19daa08ed828c..2cdf64ddb5be62f28623aa297ca9d25994e59790 100644
--- a/GUI/Model/Sample/ItemWithParticles.cpp
+++ b/GUI/Model/Sample/ItemWithParticles.cpp
@@ -14,7 +14,6 @@
 
 #include "GUI/Model/Sample/ItemWithParticles.h"
 #include "Base/Vector/RotMatrix.h"
-#include "GUI/Model/CatSample/RotationItemCatalog.h"
 #include "GUI/Support/XML/Serialize.h"
 #include "Sample/Particle/IParticle.h"
 #include "Sample/Scattering/Rotations.h"
@@ -26,7 +25,7 @@ ItemWithParticles::ItemWithParticles(const QString& abundanceTooltip,
     m_abundance.init("Abundance", abundanceTooltip, 1.0, Unit::unitless, 3 /* decimals */,
                      RealLimits::limited(0.0, 1.0), "abundance");
     m_position.init("Position Offset", positionTooltip, Unit::nanometer, "pos");
-    m_rotation.init<RotationItemCatalog>("Rotation", "", "rotation");
+    m_rotation.init("Rotation", "", "rotation");
 }
 
 std::unique_ptr<IRotation> ItemWithParticles::createRotation() const
diff --git a/GUI/Model/Sample/ItemWithParticles.h b/GUI/Model/Sample/ItemWithParticles.h
index 1b4bdd3e5aa9db603b5b523fb07f0b592ff58900..a6d801395ad6edfdd2bb1e5d58675e9698f81f1d 100644
--- a/GUI/Model/Sample/ItemWithParticles.h
+++ b/GUI/Model/Sample/ItemWithParticles.h
@@ -15,10 +15,11 @@
 #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H
 #define BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H
 
+#include "GUI/Model/CatSample/RotationItemCatalog.h"
+#include "GUI/Model/Sample/RotationItems.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Descriptor/VectorProperty.h"
 #include "GUI/Model/Sample/Item3D.h"
-#include "GUI/Model/Sample/RotationItems.h"
 #include <memory>
 
 class IRotation;
@@ -57,7 +58,7 @@ protected:
 
     DoubleProperty m_abundance;
     VectorProperty m_position;
-    SelectionProperty<RotationItem*> m_rotation;
+    SelectionProperty<RotationItem*, RotationItemCatalog> m_rotation;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H
diff --git a/GUI/Model/Sample/MesocrystalItem.cpp b/GUI/Model/Sample/MesocrystalItem.cpp
index aedcfb8869cc07458be5359b36890fbdab999a4f..dd3d56576b926be8f04c1f90d6af7c7214960006 100644
--- a/GUI/Model/Sample/MesocrystalItem.cpp
+++ b/GUI/Model/Sample/MesocrystalItem.cpp
@@ -13,9 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Sample/MesocrystalItem.h"
-#include "GUI/Model/CatSample/FormFactorItemCatalog.h"
-#include "GUI/Model/CatSample/ItemWithParticlesCatalog.h"
-#include "GUI/Model/CatSample/RotationItemCatalog.h"
 #include "GUI/Model/Sample/CompoundItem.h"
 #include "GUI/Model/Sample/CoreAndShellItem.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
@@ -60,8 +57,8 @@ MesocrystalItem::MesocrystalItem(const MaterialItems* materials)
     m_vectorC.init("Third lattice vector", "Coordinates of the third lattice vector",
                    Unit::nanometer, "vectorC");
 
-    m_outerShape.init<FormFactorItemCatalog>("Outer Shape", "", "outerShape");
-    m_basisParticle.init<ItemWithParticlesCatalog>("Basis", "", "basis", materials);
+    m_outerShape.init("Outer Shape", "", "outerShape");
+    m_basisParticle.init("Basis", "", "basis", materials);
 }
 
 void MesocrystalItem::serialize(Streamer& s)
diff --git a/GUI/Model/Sample/MesocrystalItem.h b/GUI/Model/Sample/MesocrystalItem.h
index 44d448c5c6bee48dc09e9a3be7f3fd5685f3ba67..444c03435aff6dddfd80c3565b99e0f5cb941059 100644
--- a/GUI/Model/Sample/MesocrystalItem.h
+++ b/GUI/Model/Sample/MesocrystalItem.h
@@ -15,6 +15,8 @@
 #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_MESOCRYSTALITEM_H
 #define BORNAGAIN_GUI_MODEL_SAMPLE_MESOCRYSTALITEM_H
 
+#include "GUI/Model/CatSample/FormFactorItemCatalog.h"
+#include "GUI/Model/CatSample/ItemWithParticlesCatalog.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Descriptor/VectorProperty.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
@@ -65,8 +67,8 @@ private:
     VectorProperty m_vectorA;
     VectorProperty m_vectorB;
     VectorProperty m_vectorC;
-    SelectionProperty<FormFactorItem*> m_outerShape;
-    SelectionProperty<ItemWithParticles*> m_basisParticle;
+    SelectionProperty<FormFactorItem*, FormFactorItemCatalog> m_outerShape;
+    SelectionProperty<ItemWithParticles*, ItemWithParticlesCatalog> m_basisParticle;
     const MaterialItems* m_materials;
 };
 
diff --git a/GUI/Model/Sample/ParticleItem.cpp b/GUI/Model/Sample/ParticleItem.cpp
index c86565deaad621b6af2df7c76a78d20dc9a374c7..624fdd51300ac2796c27f3e3f425c97405d1b825 100644
--- a/GUI/Model/Sample/ParticleItem.cpp
+++ b/GUI/Model/Sample/ParticleItem.cpp
@@ -13,8 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Sample/ParticleItem.h"
-#include "GUI/Model/CatSample/FormFactorItemCatalog.h"
-#include "GUI/Model/CatSample/RotationItemCatalog.h"
 #include "GUI/Model/Sample/CoreAndShellItem.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
 #include "GUI/Model/Sample/MaterialItem.h"
@@ -44,7 +42,7 @@ ParticleItem::ParticleItem(const MaterialItems* materials)
     : ItemWithMaterial(materials)
     , ItemWithParticles(abundance_tooltip, position_tooltip)
 {
-    m_formFactor.init<FormFactorItemCatalog>("Form Factor", "", "formFactor");
+    m_formFactor.init("Form Factor", "", "formFactor");
     m_formFactor.set(new CylinderItem());
 }
 
diff --git a/GUI/Model/Sample/ParticleItem.h b/GUI/Model/Sample/ParticleItem.h
index 9983499ef45ae29eb7ddb4c54ffb9253756a6f0b..d507adf2bea7e400ef7d4cff97b9c051941438c2 100644
--- a/GUI/Model/Sample/ParticleItem.h
+++ b/GUI/Model/Sample/ParticleItem.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLEITEM_H
 #define BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLEITEM_H
 
+#include "GUI/Model/CatSample/FormFactorItemCatalog.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Sample/FormFactorItems.h"
 #include "GUI/Model/Sample/ItemWithMaterial.h"
@@ -37,7 +38,7 @@ public:
     QVector<ItemWithParticles*> containedItemsWithParticles() const override;
 
 private:
-    SelectionProperty<FormFactorItem*> m_formFactor;
+    SelectionProperty<FormFactorItem*, FormFactorItemCatalog> m_formFactor;
 };
 
 template <typename T>
diff --git a/GUI/Model/Sample/ParticleLayoutItem.cpp b/GUI/Model/Sample/ParticleLayoutItem.cpp
index d2eabe72d403e05d43495d1cb9621fcdceadcb32..dc5258987f1c2875d26254ab5a7a454189700e47 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.cpp
+++ b/GUI/Model/Sample/ParticleLayoutItem.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Sample/ParticleLayoutItem.h"
-#include "GUI/Model/CatSample/InterferenceItemCatalog.h"
 #include "GUI/Model/CatSample/ItemWithParticlesCatalog.h"
 #include "GUI/Model/Sample/CompoundItem.h"
 #include "GUI/Model/Sample/InterferenceItems.h"
@@ -40,7 +39,7 @@ ParticleLayoutItem::ParticleLayoutItem(const MaterialItems* materials)
                       0.0005, Unit::nanometerMinus2, 10 /* decimals */, 0.0001 /* step */,
                       RealLimits::nonnegative(), "density");
 
-    m_interference.init<InterferenceItemCatalog>("Interference function", "", "interference");
+    m_interference.init("Interference function", "", "interference");
 }
 
 double ParticleLayoutItem::totalDensityValue() const
diff --git a/GUI/Model/Sample/ParticleLayoutItem.h b/GUI/Model/Sample/ParticleLayoutItem.h
index 693a9bfca05ee15a0c13699475be6d805118dac1..94da8e75cf4209041ddbfe306d1333a1477fd418 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.h
+++ b/GUI/Model/Sample/ParticleLayoutItem.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLELAYOUTITEM_H
 #define BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLELAYOUTITEM_H
 
+#include "GUI/Model/CatSample/InterferenceItemCatalog.h"
 #include "GUI/Model/Descriptor/DoubleProperty.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
 #include "GUI/Model/Sample/InterferenceItems.h"
@@ -72,7 +73,7 @@ public:
 
 private:
     DoubleProperty m_ownDensity;
-    SelectionProperty<InterferenceItem*> m_interference;
+    SelectionProperty<InterferenceItem*, InterferenceItemCatalog> m_interference;
     QVector<ItemWithParticles*> m_particles;
     const MaterialItems* m_materials;
 };