From 4c50b8f51625180ce42a2f52ab9ffe4d13fac4c5 Mon Sep 17 00:00:00 2001
From: Dmitry Yurov <d.yurov@fz-juelich.de>
Date: Tue, 10 Apr 2018 17:24:49 +0200
Subject: [PATCH] Introduced DomainObjectBuilder::createUnitConverter

Redmine: #2030
For later use in JobItemUtils
---
 GUI/coregui/Models/DomainObjectBuilder.cpp | 38 ++++++++++++++++++++++
 GUI/coregui/Models/DomainObjectBuilder.h   |  5 +++
 2 files changed, 43 insertions(+)

diff --git a/GUI/coregui/Models/DomainObjectBuilder.cpp b/GUI/coregui/Models/DomainObjectBuilder.cpp
index a599ebd0af2..010387c6ce6 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.cpp
+++ b/GUI/coregui/Models/DomainObjectBuilder.cpp
@@ -13,15 +13,22 @@
 // ************************************************************************** //
 
 #include "DomainObjectBuilder.h"
+#include "AxesItems.h"
 #include "BeamItems.h"
 #include "ComboProperty.h"
 #include "GUIHelpers.h"
+#include "IDetector2D.h"
 #include "InstrumentItems.h"
 #include "InterferenceFunctionItems.h"
 #include "LayerItem.h"
 #include "ParticleDistributionItem.h"
 #include "ParticleLayoutItem.h"
+#include "SimpleUnitConverters.h"
+#include "SpecularBeamInclinationItem.h"
 #include "TransformToDomain.h"
+#include "UnitConverter1D.h"
+#include "UnitConverterUtils.h"
+#include "Units.h"
 
 std::unique_ptr<MultiLayer> DomainObjectBuilder::buildMultiLayer(const SessionItem& multilayer_item)
 {
@@ -123,3 +130,34 @@ DomainObjectBuilder::buildInstrument(const InstrumentItem& instrumentItem)
 {
     return instrumentItem.createInstrument();
 }
+
+std::unique_ptr<IUnitConverter>
+DomainObjectBuilder::createUnitConverter(const InstrumentItem* instrumentItem)
+{
+    const auto instrument = instrumentItem->createInstrument();
+    instrument->initDetector();
+
+    if (instrumentItem->modelType() == Constants::GISASInstrumentType)
+        return UnitConverterUtils::createConverterForGISAS(*instrument);
+
+    if (instrumentItem->modelType() == Constants::SpecularInstrumentType)
+    {
+        auto axis_item = dynamic_cast<BasicAxisItem*>(
+            instrumentItem->beamItem()
+                ->getItem(SpecularBeamItem::P_INCLINATION_ANGLE)
+                ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
+        return std::make_unique<UnitConverter1D>(instrument->getBeam(),
+                                                 *axis_item->createAxis(Units::degree));
+    }
+
+    if (instrumentItem->modelType() == Constants::OffSpecInstrumentType) {
+        auto axis_item = dynamic_cast<BasicAxisItem*>(
+            instrumentItem->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS));
+        const auto detector2d = dynamic_cast<const IDetector2D*>(instrument->getDetector());
+        return std::make_unique<OffSpecularConverter>(*detector2d, instrument->getBeam(),
+                                                      *axis_item->createAxis(Units::degree));
+    }
+
+    throw GUIHelpers::Error(
+        "Error in DomainObjectBuilder::createUnitConverter: unknown instrument type.");
+}
diff --git a/GUI/coregui/Models/DomainObjectBuilder.h b/GUI/coregui/Models/DomainObjectBuilder.h
index 80d66ea0cd7..ed03b455f51 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.h
+++ b/GUI/coregui/Models/DomainObjectBuilder.h
@@ -25,6 +25,7 @@ class ParticleLayout;
 class IInterferenceFunction;
 class SessionItem;
 class InstrumentItem;
+class IUnitConverter;
 
 namespace DomainObjectBuilder
 {
@@ -34,6 +35,10 @@ BA_CORE_API_ std::unique_ptr<ParticleLayout> buildParticleLayout(const SessionIt
 BA_CORE_API_ std::unique_ptr<IInterferenceFunction>
 buildInterferenceFunction(const SessionItem& item);
 BA_CORE_API_ std::unique_ptr<Instrument> buildInstrument(const InstrumentItem& instrumentItem);
+
+//! Creates a unit converter corresponding to the given instrument item
+BA_CORE_API_ std::unique_ptr<IUnitConverter>
+createUnitConverter(const InstrumentItem* instrumentItem);
 };
 
 #endif // DOMAINOBJECTBUILDER_H
-- 
GitLab