From d862d399db47c2fce9dbb7187d167cee801f571b Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Thu, 9 Mar 2017 17:30:02 +0100
Subject: [PATCH] Beam domain is build on board of corresponding item.

---
 GUI/coregui/Models/BeamItem.cpp            | 18 ++++++++++
 GUI/coregui/Models/BeamItem.h              |  8 +++--
 GUI/coregui/Models/DomainObjectBuilder.cpp | 41 ++++++++++++----------
 GUI/coregui/Models/DomainObjectBuilder.h   |  4 +--
 GUI/coregui/Models/TransformToDomain.cpp   | 39 +-------------------
 GUI/coregui/Models/TransformToDomain.h     |  2 --
 6 files changed, 49 insertions(+), 63 deletions(-)

diff --git a/GUI/coregui/Models/BeamItem.cpp b/GUI/coregui/Models/BeamItem.cpp
index 110732c4f2f..3c8574c9d65 100644
--- a/GUI/coregui/Models/BeamItem.cpp
+++ b/GUI/coregui/Models/BeamItem.cpp
@@ -20,6 +20,9 @@
 #include "ScientificDoubleProperty.h"
 #include "BeamWavelengthItem.h"
 #include "BeamAngleItems.h"
+#include "GUIHelpers.h"
+#include "Units.h"
+#include "Beam.h"
 
 const QString BeamItem::P_INTENSITY = QString::fromStdString(BornAgain::Intensity);
 const QString BeamItem::P_WAVELENGTH = QString::fromStdString(BornAgain::Wavelength);
@@ -35,6 +38,8 @@ BeamItem::BeamItem() : SessionItem(Constants::BeamType)
     addGroupProperty(P_AZIMUTHAL_ANGLE, Constants::BeamAzimuthalAngleType);
 }
 
+BeamItem::~BeamItem(){}
+
 double BeamItem::getIntensity() const
 {
     ScientificDoubleProperty intensity
@@ -102,3 +107,16 @@ void BeamItem::setAzimuthalAngle(double value, const QString &distribution_name)
     Q_ASSERT(distributionItem);
     distributionItem->setItemValue(DistributionNoneItem::P_VALUE, value);
 }
+
+std::unique_ptr<Beam> BeamItem::createBeam() const
+{
+    auto result = GUIHelpers::make_unique<Beam>();
+
+    result->setIntensity(getIntensity());
+    double lambda = getWavelength();
+    double inclination_angle = Units::deg2rad(getInclinationAngle());
+    double azimuthal_angle = Units::deg2rad(getAzimuthalAngle());
+    result->setCentralK(lambda, inclination_angle, azimuthal_angle);
+
+    return std::move(result);
+}
diff --git a/GUI/coregui/Models/BeamItem.h b/GUI/coregui/Models/BeamItem.h
index 644a86bec44..135c26683cc 100644
--- a/GUI/coregui/Models/BeamItem.h
+++ b/GUI/coregui/Models/BeamItem.h
@@ -19,6 +19,8 @@
 
 #include "SessionItem.h"
 
+class Beam;
+
 class BA_CORE_API_ BeamItem : public SessionItem
 {
 
@@ -27,8 +29,8 @@ public:
     static const QString P_WAVELENGTH;
     static const QString P_INCLINATION_ANGLE;
     static const QString P_AZIMUTHAL_ANGLE;
-    explicit BeamItem();
-    virtual ~BeamItem(){}
+    BeamItem();
+    virtual ~BeamItem();
 
     double getIntensity() const;
     void setIntensity(double value);
@@ -41,6 +43,8 @@ public:
 
     double getAzimuthalAngle() const;
     void setAzimuthalAngle(double value, const QString &distribution_name = QString());
+
+    std::unique_ptr<Beam> createBeam() const;
 };
 
 #endif // BEAMITEM_H
diff --git a/GUI/coregui/Models/DomainObjectBuilder.cpp b/GUI/coregui/Models/DomainObjectBuilder.cpp
index 969a5b291c7..96fe6bf5870 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.cpp
+++ b/GUI/coregui/Models/DomainObjectBuilder.cpp
@@ -25,6 +25,12 @@
 #include "ParticleLayoutItem.h"
 #include "InterferenceFunctionItems.h"
 #include "TransformToDomain.h"
+#include "InstrumentItem.h"
+#include "Instrument.h"
+#include "BeamItem.h"
+#include "DetectorItems.h"
+#include "IResolutionFunction2D.h"
+
 
 std::unique_ptr<MultiLayer> DomainObjectBuilder::buildMultiLayer(
     const SessionItem& multilayer_item) const
@@ -124,25 +130,22 @@ DomainObjectBuilder::buildInterferenceFunction(const SessionItem& item) const
     return iffItem->createInterferenceFunction();
 }
 
-std::unique_ptr<Instrument> DomainObjectBuilder::buildInstrument(
-    const SessionItem& instrument_item) const
+std::unique_ptr<Instrument> DomainObjectBuilder::buildInstrument(const InstrumentItem& instrumentItem) const
 {
-    auto P_instrument = TransformToDomain::createInstrument(instrument_item);
-    QVector<SessionItem *> children = instrument_item.childItems();
-    for (int i = 0; i < children.size(); ++i) {
-        if (children[i]->modelType() == Constants::BeamType) {
-            auto P_beam = buildBeam(*children[i]);
-            if (P_beam) {
-                P_instrument->setBeam(*P_beam);
-            }
-        } else if (children[i]->modelType() == Constants::DetectorContainerType) {
-            TransformToDomain::initInstrumentFromDetectorItem(*children[i], P_instrument.get());
-        }
-    }
-    return P_instrument;
-}
+    auto instrument = GUIHelpers::make_unique<Instrument>();
 
-std::unique_ptr<Beam> DomainObjectBuilder::buildBeam(const SessionItem& item) const
-{
-    return TransformToDomain::createBeam(item);
+    auto beam = instrumentItem.beamItem()->createBeam();
+    instrument->setBeam(*beam);
+
+    auto detector = instrumentItem.detectorItem()->createDetector();
+    instrument->setDetector(*detector);
+
+    auto resfunc = instrumentItem.detectorItem()->createResolutionFunction();
+    if(resfunc)
+        instrument->setDetectorResolutionFunction(*resfunc);
+
+     TransformToDomain::initInstrumentFromDetectorItem(*instrumentItem.detectorContainerItem(),
+                                                       instrument.get());
+
+    return instrument;
 }
diff --git a/GUI/coregui/Models/DomainObjectBuilder.h b/GUI/coregui/Models/DomainObjectBuilder.h
index 26ac0f23eff..b1de2fc458b 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.h
+++ b/GUI/coregui/Models/DomainObjectBuilder.h
@@ -27,6 +27,7 @@ class ParticleLayout;
 class IInterferenceFunction;
 class Beam;
 class SessionItem;
+class InstrumentItem;
 
 class BA_CORE_API_ DomainObjectBuilder
 {
@@ -36,8 +37,7 @@ public:
     std::unique_ptr<ParticleLayout> buildParticleLayout(const SessionItem &item) const;
     std::unique_ptr<IInterferenceFunction>
     buildInterferenceFunction(const SessionItem &item) const;
-    std::unique_ptr<Instrument> buildInstrument(const SessionItem &instrument_item) const;
-    std::unique_ptr<Beam> buildBeam(const SessionItem &item) const;
+    std::unique_ptr<Instrument> buildInstrument(const InstrumentItem& instrumentItem) const;
 };
 
 #endif // DOMAINOBJECTBUILDER_H
diff --git a/GUI/coregui/Models/TransformToDomain.cpp b/GUI/coregui/Models/TransformToDomain.cpp
index 802dac82d51..1c3f5d89dd3 100644
--- a/GUI/coregui/Models/TransformToDomain.cpp
+++ b/GUI/coregui/Models/TransformToDomain.cpp
@@ -144,26 +144,6 @@ std::unique_ptr<ParticleDistribution> TransformToDomain::createParticleDistribut
     return P_part_distr;
 }
 
-std::unique_ptr<Instrument> TransformToDomain::createInstrument(const SessionItem& item)
-{
-    Q_UNUSED(item);
-    return GUIHelpers::make_unique<Instrument>();
-}
-
-std::unique_ptr<Beam> TransformToDomain::createBeam(const SessionItem& item)
-{
-    auto P_beam = GUIHelpers::make_unique<Beam>();
-
-    auto beamItem = dynamic_cast<const BeamItem*>(&item);
-    P_beam->setIntensity(beamItem->getIntensity());
-    double lambda = beamItem->getWavelength();
-    double inclination_angle = Units::deg2rad(beamItem->getInclinationAngle());
-    double azimuthal_angle = Units::deg2rad(beamItem->getAzimuthalAngle());
-    P_beam->setCentralK(lambda, inclination_angle, azimuthal_angle);
-
-    return P_beam;
-}
-
 void TransformToDomain::initInstrumentFromDetectorItem(const SessionItem& detectorItem,
                                                        Instrument* instrument)
 {
@@ -171,25 +151,8 @@ void TransformToDomain::initInstrumentFromDetectorItem(const SessionItem& detect
     Q_ASSERT(subDetector);
 
     double scale(1.0);
-    if(auto sphericalDetector = dynamic_cast<SphericalDetectorItem*>(subDetector)) {
+    if(dynamic_cast<SphericalDetectorItem*>(subDetector))
         scale = Units::degree;
-        auto detector = sphericalDetector->createDetector();
-        instrument->setDetector(*detector);
-        auto resfunc = sphericalDetector->createResolutionFunction();
-        if(resfunc) instrument->setDetectorResolutionFunction(*resfunc);
-    }
-
-    else if(auto rectangularDetector = dynamic_cast<RectangularDetectorItem*>(subDetector)) {
-        auto detector = rectangularDetector->createDetector();
-        instrument->setDetector(*detector);
-        auto resfunc = rectangularDetector->createResolutionFunction();
-        if(resfunc) instrument->setDetectorResolutionFunction(*resfunc);
-
-    } else {
-        throw GUIHelpers::Error(
-            "TransformToDomain::initInstrumentWithDetectorItem() -> Error. Unknown model type "
-            + subDetector->modelType());
-    }
 
     if(auto maskContainerItem = detectorItem.getChildOfType(Constants::MaskContainerType)) {
         for(int i_row = maskContainerItem->childItems().size(); i_row>0; --i_row) {
diff --git a/GUI/coregui/Models/TransformToDomain.h b/GUI/coregui/Models/TransformToDomain.h
index d9378960879..7957cd2e89d 100644
--- a/GUI/coregui/Models/TransformToDomain.h
+++ b/GUI/coregui/Models/TransformToDomain.h
@@ -35,10 +35,8 @@ class SessionItem;
 
 namespace TransformToDomain
 {
-BA_CORE_API_ std::unique_ptr<Beam> createBeam(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<IMaterial> createDomainMaterial(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<IParticle> createIParticle(const SessionItem& item);
-BA_CORE_API_ std::unique_ptr<Instrument> createInstrument(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<Layer> createLayer(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<LayerRoughness> createLayerRoughness(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<MultiLayer> createMultiLayer(const SessionItem& item);
-- 
GitLab