From e5280870daca80543927b85a339381e46e87f8f1 Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Wed, 2 Feb 2022 11:12:01 +0100
Subject: [PATCH] replace SessionItem-hierarchy-based instrument location

---
 GUI/Model/Item/BeamItems.cpp                   |  4 ++--
 GUI/Model/Item/BeamItems.h                     |  2 +-
 GUI/Model/Item/InstrumentItems.cpp             | 11 +++--------
 GUI/Model/Item/InstrumentItems.h               |  3 +--
 GUI/Model/Item/PointwiseAxisItem.cpp           | 16 ++++++----------
 GUI/Model/Item/PointwiseAxisItem.h             |  6 +++---
 GUI/Model/Item/SpecularBeamInclinationItem.cpp |  6 +++++-
 GUI/Model/Item/SpecularBeamInclinationItem.h   |  4 +++-
 8 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/GUI/Model/Item/BeamItems.cpp b/GUI/Model/Item/BeamItems.cpp
index 30f8937d4fd..874818461c5 100644
--- a/GUI/Model/Item/BeamItems.cpp
+++ b/GUI/Model/Item/BeamItems.cpp
@@ -119,9 +119,9 @@ template <typename T> void BeamItem::initInclinationAngle()
 // Specular beam item
 /* ------------------------------------------------------------------------- */
 
-SpecularBeamItem::SpecularBeamItem()
+SpecularBeamItem::SpecularBeamItem(const InstrumentItem* owningInstrument)
 {
-    initInclinationAngle<SpecularBeamInclinationItem>();
+    m_inclinationAngleItem.reset(new SpecularBeamInclinationItem(owningInstrument));
     initWavelength<SpecularBeamWavelengthItem>();
 
     m_footprint.init<FootprintItemCatalog>("Type", "Footprint type", "footprint");
diff --git a/GUI/Model/Item/BeamItems.h b/GUI/Model/Item/BeamItems.h
index 623efb2552c..bd753e0d4de 100644
--- a/GUI/Model/Item/BeamItems.h
+++ b/GUI/Model/Item/BeamItems.h
@@ -66,7 +66,7 @@ protected:
 
 class SpecularBeamItem : public BeamItem {
 public:
-    SpecularBeamItem();
+    explicit SpecularBeamItem(const InstrumentItem* owningInstrument);
     void serialize(Serializer& s) override;
 
     double getInclinationAngle() const override;
diff --git a/GUI/Model/Item/InstrumentItems.cpp b/GUI/Model/Item/InstrumentItems.cpp
index 9706dc014d5..197f4eff842 100644
--- a/GUI/Model/Item/InstrumentItems.cpp
+++ b/GUI/Model/Item/InstrumentItems.cpp
@@ -133,11 +133,6 @@ void InstrumentItem::setWithPolarizerAnalyzer(bool with)
     m_withPolarizerAnalyzer = with;
 }
 
-template <typename T> void InstrumentItem::addBeam()
-{
-    m_beam.reset(new T());
-}
-
 template <typename T> T* InstrumentItem::beam() const
 {
     return dynamic_cast<T*>(m_beam.get());
@@ -164,7 +159,7 @@ void InstrumentItem::serialize(Serializer& s)
 
 SpecularInstrumentItem::SpecularInstrumentItem()
 {
-    addBeam<SpecularBeamItem>();
+    m_beam.reset(new SpecularBeamItem(this));
 }
 
 SpecularBeamItem* SpecularInstrumentItem::beamItem() const
@@ -247,7 +242,7 @@ QString SpecularInstrumentItem::defaultName() const
 
 DepthProbeInstrumentItem::DepthProbeInstrumentItem()
 {
-    addBeam<SpecularBeamItem>();
+    m_beam.reset(new SpecularBeamItem(this));
 
     auto* axisItem = beamItem()->inclinationAxis();
     axisItem->setLowerBound(0.0);
@@ -324,7 +319,7 @@ ICoordSystem* DepthProbeInstrumentItem::createCoordSystem() const
 
 Instrument2DItem::Instrument2DItem()
 {
-    addBeam<GISASBeamItem>();
+    m_beam.reset(new GISASBeamItem());
     m_detector.init<DetectorItemCatalog>("Detector", "", "detector");
 }
 
diff --git a/GUI/Model/Item/InstrumentItems.h b/GUI/Model/Item/InstrumentItems.h
index bd197206bdc..6896c8f4fb6 100644
--- a/GUI/Model/Item/InstrumentItems.h
+++ b/GUI/Model/Item/InstrumentItems.h
@@ -89,10 +89,9 @@ public:
 protected:
     explicit InstrumentItem(const QString& modelType);
 
-    template <typename T> void addBeam();
     template <typename T> T* beam() const;
 
-private:
+protected:
     QString m_id;
     QString m_name;
     QString m_description;
diff --git a/GUI/Model/Item/PointwiseAxisItem.cpp b/GUI/Model/Item/PointwiseAxisItem.cpp
index fe04699a37a..8de711facbb 100644
--- a/GUI/Model/Item/PointwiseAxisItem.cpp
+++ b/GUI/Model/Item/PointwiseAxisItem.cpp
@@ -52,7 +52,12 @@ void PointwiseAxisItem::init(const IAxis& axis, const QString& units_label)
 {
     m_axis = std::unique_ptr<IAxis>(axis.clone());
     setItemValue(P_NATIVE_AXIS_UNITS, units_label);
-    findInstrument();
+}
+
+void PointwiseAxisItem::setOwningInstrument(const InstrumentItem* instrument)
+{
+    // only specular instruments are relevant
+    m_instrument = dynamic_cast<const SpecularInstrumentItem*>(instrument);
 }
 
 const IAxis* PointwiseAxisItem::axis() const
@@ -101,7 +106,6 @@ void PointwiseAxisItem::deserializeBinaryData(const QByteArray& data)
     std::istringstream str(data.toStdString());
     std::unique_ptr<OutputData<double>> d(OutputDataReadWriteINT().readOutputData(str));
     m_axis = std::unique_ptr<IAxis>(d->axis(0).clone());
-    findInstrument();
 }
 
 bool PointwiseAxisItem::checkValidity() const
@@ -109,14 +113,6 @@ bool PointwiseAxisItem::checkValidity() const
     return m_axis && m_instrument && getUnitsLabel() != "nbins";
 }
 
-void PointwiseAxisItem::findInstrument()
-{
-    SessionItem* parent_item = parent();
-    while (parent_item && !dynamic_cast<SpecularInstrumentItem*>(parent_item))
-        parent_item = parent_item->parent();
-    m_instrument = dynamic_cast<SpecularInstrumentItem*>(parent_item);
-}
-
 void PointwiseAxisItem::updateIndicators()
 {
     if (!checkValidity())
diff --git a/GUI/Model/Item/PointwiseAxisItem.h b/GUI/Model/Item/PointwiseAxisItem.h
index 51d97e4d9b7..de8a320980a 100644
--- a/GUI/Model/Item/PointwiseAxisItem.h
+++ b/GUI/Model/Item/PointwiseAxisItem.h
@@ -19,6 +19,7 @@
 
 class PointwiseAxis;
 class SpecularInstrumentItem;
+class InstrumentItem;
 
 //! Item for non-uniform axis with specified coordinates.
 class PointwiseAxisItem : public BasicAxisItem {
@@ -35,6 +36,8 @@ public:
 
     // setters, getters
     void init(const IAxis& axis, const QString& units_label);
+    void setOwningInstrument(const InstrumentItem* instrument);
+
     const IAxis* axis() const;
     QString getUnitsLabel() const;
 
@@ -48,9 +51,6 @@ public:
 private:
     bool checkValidity() const;
 
-    //! Sets internal m_instrument to containing SpecularInstrumentItem
-    void findInstrument();
-
     const SpecularInstrumentItem* m_instrument;
     std::unique_ptr<IAxis> m_axis;
 };
diff --git a/GUI/Model/Item/SpecularBeamInclinationItem.cpp b/GUI/Model/Item/SpecularBeamInclinationItem.cpp
index 3d52b5dc3ee..fa561d849c3 100644
--- a/GUI/Model/Item/SpecularBeamInclinationItem.cpp
+++ b/GUI/Model/Item/SpecularBeamInclinationItem.cpp
@@ -60,8 +60,9 @@ void initDistribution(DistributionItem* newDistribution,
 
 } // namespace
 
-SpecularBeamInclinationItem::SpecularBeamInclinationItem()
+SpecularBeamInclinationItem::SpecularBeamInclinationItem(const InstrumentItem* owningInstrument)
     : BeamDistributionItem()
+    , m_owningInstrument(owningInstrument)
 {
     m_distribution.init<DistributionItemCatalog>("Distribution", "", "distribution",
                                                  DistributionItemCatalog::symmetricTypes(),
@@ -83,6 +84,8 @@ void SpecularBeamInclinationItem::serialize(Serializer& s)
     if (s.isReading()) {
         m_distribution->setLimits(RealLimits::limited(-90.0, 90.0));
         m_distribution->setUnit(Unit::degree);
+        if (m_pointwiseAlphaAxis)
+            m_pointwiseAlphaAxis->setOwningInstrument(m_owningInstrument);
     }
 }
 
@@ -121,6 +124,7 @@ void SpecularBeamInclinationItem::initPointwiseAxis(const IAxis& axis, QString u
 {
     if (!m_pointwiseAlphaAxis) {
         m_pointwiseAlphaAxis.reset(new PointwiseAxisItem());
+        m_pointwiseAlphaAxis->setOwningInstrument(m_owningInstrument);
         setAxisPresentationDefaults(m_pointwiseAlphaAxis.get());
     }
 
diff --git a/GUI/Model/Item/SpecularBeamInclinationItem.h b/GUI/Model/Item/SpecularBeamInclinationItem.h
index 10dea5f6f5e..a8cdabe61c3 100644
--- a/GUI/Model/Item/SpecularBeamInclinationItem.h
+++ b/GUI/Model/Item/SpecularBeamInclinationItem.h
@@ -25,7 +25,7 @@
 
 class SpecularBeamInclinationItem : public BeamDistributionItem {
 public:
-    SpecularBeamInclinationItem();
+    explicit SpecularBeamInclinationItem(const InstrumentItem* owningInstrument);
 
     void serialize(Serializer& s) override;
     double scaleFactor() const override;
@@ -46,6 +46,8 @@ private:
     std::unique_ptr<BasicAxisItem> m_uniformAlphaAxis;
     std::unique_ptr<PointwiseAxisItem> m_pointwiseAlphaAxis;
     bool m_currentAxisIsUniformAxis;
+
+    const InstrumentItem* m_owningInstrument;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_ITEM_SPECULARBEAMINCLINATIONITEM_H
-- 
GitLab