From 8cf8e9d0bdb75ffc87227e1040dafc906d0936e3 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 27 Jul 2021 15:10:41 +0200
Subject: [PATCH] CoordSystem2D no longer dependent on Beam

---
 Core/Simulation/DepthProbeSimulation.cpp      |  3 +-
 Core/Simulation/OffSpecularSimulation.cpp     |  6 ++-
 Device/Instrument/CoordSystem2D.cpp           | 44 +++++++++----------
 Device/Instrument/CoordSystem2D.h             | 23 ++++++----
 Device/Instrument/Instrument.cpp              |  7 ++-
 GUI/Models/InstrumentItems.cpp                |  5 ++-
 .../Core/Core/DepthProbeConverterTest.cpp     |  9 ++--
 .../Instrument/OffSpecularConverterTest.cpp   |  3 +-
 .../Instrument/RectangularConverterTest.cpp   |  9 ++--
 .../Instrument/SphericalConverterTest.cpp     |  6 ++-
 auto/Wrap/doxygenDevice.i                     |  8 ++--
 11 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/Core/Simulation/DepthProbeSimulation.cpp b/Core/Simulation/DepthProbeSimulation.cpp
index 8e2a6426fca..dfd04e3212f 100644
--- a/Core/Simulation/DepthProbeSimulation.cpp
+++ b/Core/Simulation/DepthProbeSimulation.cpp
@@ -92,7 +92,8 @@ size_t DepthProbeSimulation::intensityMapSize() const
 #ifndef SWIG
 ICoordSystem* DepthProbeSimulation::createCoordSystem() const
 {
-    return new DepthProbeCoordinates(beam(), *m_alpha_axis, *m_z_axis);
+    return new DepthProbeCoordinates(beam().direction(), beam().wavelength(),
+                                     *m_alpha_axis, *m_z_axis);
 }
 #endif
 
diff --git a/Core/Simulation/OffSpecularSimulation.cpp b/Core/Simulation/OffSpecularSimulation.cpp
index 350dbd4cbde..290aef11db4 100644
--- a/Core/Simulation/OffSpecularSimulation.cpp
+++ b/Core/Simulation/OffSpecularSimulation.cpp
@@ -82,10 +82,12 @@ ICoordSystem* OffSpecularSimulation::createCoordSystem() const
 
     if (const auto* rect_det = dynamic_cast<const RectangularDetector*>(&detector2D())) {
         std::unique_ptr<RectangularPixel> det_pixel(rect_det->regionOfInterestPixel());
-        return OffSpecularCoordinates::createForRectangularDetector(beam(), *beamAxis(), *det_pixel,
+        return OffSpecularCoordinates::createForRectangularDetector(beam().direction(),
+                                                                    *beamAxis(), *det_pixel,
                                                                     yAxis);
     } else if (dynamic_cast<const SphericalDetector*>(&detector2D()))
-        return OffSpecularCoordinates::createForSphericalDetector(beam(), *beamAxis(), yAxis);
+        return OffSpecularCoordinates::createForSphericalDetector(beam().direction(),
+                                                                  *beamAxis(), yAxis);
 
     ASSERT(0);
     return nullptr;
diff --git a/Device/Instrument/CoordSystem2D.cpp b/Device/Instrument/CoordSystem2D.cpp
index 032be4ac44b..fb9ffa67291 100644
--- a/Device/Instrument/CoordSystem2D.cpp
+++ b/Device/Instrument/CoordSystem2D.cpp
@@ -18,7 +18,6 @@
 #include "Base/Math/Constants.h"
 #include "Base/Pixel/RectangularPixel.h"
 #include "Base/Utils/Assert.h"
-#include "Device/Beam/Beam.h"
 #include "Device/Coord/AxisNames.h"
 #include <algorithm>
 #include <cmath>
@@ -46,10 +45,8 @@ double axisAngle(size_t i_axis, kvector_t k_f)
 //  class CoordSystem2D
 //  ************************************************************************************************
 
-CoordSystem2D::CoordSystem2D(const Beam& beam)
-    : m_wavelength(beam.wavelength())
-    , m_alpha_i(-beam.direction().alpha())
-    , m_phi_i(beam.direction().phi())
+CoordSystem2D::CoordSystem2D(const Direction& direction, double wavelength)
+    : m_wavelength(wavelength), m_alpha_i(-direction.alpha()), m_phi_i(direction.phi())
 {
 }
 
@@ -119,8 +116,9 @@ void CoordSystem2D::addAxis(const IAxis& axis)
 //  class SphericalCoords
 //  ************************************************************************************************
 
-SphericalCoords::SphericalCoords(const CloneableVector<IAxis>& axes, const Beam& beam)
-    : CoordSystem2D(beam)
+SphericalCoords::SphericalCoords(const CloneableVector<IAxis>& axes, const Direction& direction,
+                                 double wavelength)
+    : CoordSystem2D(direction, wavelength)
 {
     ASSERT(axes.size() == 2);
 
@@ -189,8 +187,9 @@ std::vector<std::map<Axes::Coords, std::string>> SphericalCoords::createNameMaps
 //  ************************************************************************************************
 
 ImageCoords::ImageCoords(const CloneableVector<IAxis>& axes,
-                         const RectangularPixel& regionOfInterestPixel, const Beam& beam)
-    : CoordSystem2D(beam)
+                         const RectangularPixel& regionOfInterestPixel, const Direction& direction,
+                         double wavelength)
+    : CoordSystem2D(direction, wavelength)
 {
     ASSERT(axes.size() == 2);
 
@@ -267,9 +266,9 @@ std::vector<std::map<Axes::Coords, std::string>> ImageCoords::createNameMaps() c
 //  class OffSpecularCoordinates
 //  ************************************************************************************************
 
-OffSpecularCoordinates::OffSpecularCoordinates(const Beam& beam, const IAxis& alpha_axis,
+OffSpecularCoordinates::OffSpecularCoordinates(const Direction& direction, const IAxis& alpha_axis,
                                                double alpha_f_min, double alpha_f_max, size_t nbins)
-    : CoordSystem2D(beam)
+    : CoordSystem2D(direction)
 {
     addAxisData(axisName(0), alpha_axis.lowerBound(), alpha_axis.upperBound(), defaultUnits(),
                 alpha_axis.size());
@@ -282,27 +281,26 @@ OffSpecularCoordinates::OffSpecularCoordinates(const OffSpecularCoordinates& oth
 {
 }
 
-OffSpecularCoordinates*
-OffSpecularCoordinates::createForRectangularDetector(const Beam& beam, const IAxis& alphaAxis,
-                                                     const RectangularPixel& detectorPixel,
-                                                     const IAxis& yAxis)
+OffSpecularCoordinates* OffSpecularCoordinates::createForRectangularDetector(
+    const Direction& direction, const IAxis& alphaAxis, const RectangularPixel& detectorPixel,
+    const IAxis& yAxis)
 {
     const auto k00 = detectorPixel.getPosition(0.0, 0.0);
     const auto k01 = detectorPixel.getPosition(0.0, 1.0);
     const double alpha_f_min = M_PI_2 - k00.theta();
     const double alpha_f_max = M_PI_2 - k01.theta();
 
-    return new OffSpecularCoordinates(beam, alphaAxis, alpha_f_min, alpha_f_max, yAxis.size());
+    return new OffSpecularCoordinates(direction, alphaAxis, alpha_f_min, alpha_f_max, yAxis.size());
 }
 
-OffSpecularCoordinates* OffSpecularCoordinates::createForSphericalDetector(const Beam& beam,
-                                                                           const IAxis& alphaAxis,
-                                                                           const IAxis& yAxis)
+OffSpecularCoordinates*
+OffSpecularCoordinates::createForSphericalDetector(const Direction& direction,
+                                                   const IAxis& alphaAxis, const IAxis& yAxis)
 {
     const double alpha_f_min = yAxis.lowerBound();
     const double alpha_f_max = yAxis.upperBound();
 
-    return new OffSpecularCoordinates(beam, alphaAxis, alpha_f_min, alpha_f_max, yAxis.size());
+    return new OffSpecularCoordinates(direction, alphaAxis, alpha_f_min, alpha_f_max, yAxis.size());
 }
 
 OffSpecularCoordinates* OffSpecularCoordinates::clone() const
@@ -338,9 +336,9 @@ std::vector<std::map<Axes::Coords, std::string>> OffSpecularCoordinates::createN
 
 const std::string z_axis_name = "Position [nm]";
 
-DepthProbeCoordinates::DepthProbeCoordinates(const Beam& beam, const IAxis& alpha_axis,
-                                             const IAxis& z_axis)
-    : CoordSystem2D(beam)
+DepthProbeCoordinates::DepthProbeCoordinates(const Direction& direction, double wavelength,
+                                             const IAxis& alpha_axis, const IAxis& z_axis)
+    : CoordSystem2D(direction, wavelength)
 {
     const auto& alpha_axis_name = axisName(0);
     const auto& z_axis_name = axisName(1);
diff --git a/Device/Instrument/CoordSystem2D.h b/Device/Instrument/CoordSystem2D.h
index a0c3d670629..5ef5d6dd870 100644
--- a/Device/Instrument/CoordSystem2D.h
+++ b/Device/Instrument/CoordSystem2D.h
@@ -21,6 +21,7 @@
 #define BORNAGAIN_DEVICE_INSTRUMENT_COORDSYSTEM2D_H
 
 #include "Base/Types/CloneableVector.h"
+#include "Base/Vector/Direction.h"
 #include "Base/Vector/Vectors3D.h"
 #include "Device/Coord/ICoordSystem.h"
 
@@ -31,7 +32,7 @@ class RectangularPixel;
 
 class CoordSystem2D : public ICoordSystem {
 public:
-    CoordSystem2D(const Beam& beam);
+    CoordSystem2D(const Direction& direction, double wavelength=0);
     ~CoordSystem2D() override = default;
 
     virtual size_t dimension() const override { return m_axes.size(); }
@@ -80,7 +81,8 @@ private:
 
 class SphericalCoords : public CoordSystem2D {
 public:
-    SphericalCoords(const CloneableVector<IAxis>& axes, const Beam& beam);
+    SphericalCoords(const CloneableVector<IAxis>& axes, const Direction& direction,
+                    double wavelength);
     ~SphericalCoords() override;
 
     SphericalCoords* clone() const override;
@@ -103,7 +105,7 @@ private:
 class ImageCoords : public CoordSystem2D {
 public:
     ImageCoords(const CloneableVector<IAxis>& axes, const RectangularPixel& regionOfInterestPixel,
-                const Beam& beam);
+                const Direction& direction, double wavelength);
     ~ImageCoords() override;
 
     ImageCoords* clone() const override;
@@ -129,18 +131,20 @@ private:
 class OffSpecularCoordinates : public CoordSystem2D {
 public:
     static OffSpecularCoordinates*
-    createForRectangularDetector(const Beam& beam, const IAxis& alphaAxis,
-                                 const RectangularPixel& detectorPixel, const IAxis& yAxis);
+    createForRectangularDetector(const Direction& direction,
+                                 const IAxis& alphaAxis, const RectangularPixel& detectorPixel,
+                                 const IAxis& yAxis);
 
-    static OffSpecularCoordinates*
-    createForSphericalDetector(const Beam& beam, const IAxis& alphaAxis, const IAxis& yAxis);
+    static OffSpecularCoordinates* createForSphericalDetector(const Direction& direction,
+                                                              const IAxis& alphaAxis,
+                                                              const IAxis& yAxis);
 
     OffSpecularCoordinates* clone() const override;
 
     Axes::Coords defaultUnits() const override;
 
 private:
-    OffSpecularCoordinates(const Beam& beam, const IAxis& alphaAxis, double alpha_f_min,
+    OffSpecularCoordinates(const Direction& direction, const IAxis& alphaAxis, double alpha_f_min,
                            double alpha_f_max, size_t nbins);
     OffSpecularCoordinates(const OffSpecularCoordinates& other); //!< used by clone()
     double calculateValue(size_t i_axis, Axes::Coords units, double value) const override;
@@ -153,7 +157,8 @@ private:
 
 class DepthProbeCoordinates : public CoordSystem2D {
 public:
-    DepthProbeCoordinates(const Beam& beam, const IAxis& alpha_axis, const IAxis& z_axis);
+    DepthProbeCoordinates(const Direction& direction, double wavelength, const IAxis& alpha_axis,
+                          const IAxis& z_axis);
     ~DepthProbeCoordinates() override;
 
     DepthProbeCoordinates* clone() const override;
diff --git a/Device/Instrument/Instrument.cpp b/Device/Instrument/Instrument.cpp
index ae69afbf7c0..cbf09911082 100644
--- a/Device/Instrument/Instrument.cpp
+++ b/Device/Instrument/Instrument.cpp
@@ -119,11 +119,14 @@ CoordSystem2D* Instrument::createScatteringCoords() const
 
     // TODO: use virtual fcts in detector classes instead of dynamic casts here
     if (const auto* const det = dynamic_cast<const SphericalDetector*>(detector))
-        return new SphericalCoords(detector->axesClippedToRegionOfInterest(), beam());
+        return new SphericalCoords(detector->axesClippedToRegionOfInterest(), beam().direction(),
+                                   beam().wavelength());
 
     if (const auto* const det = dynamic_cast<const RectangularDetector*>(detector)) {
         std::unique_ptr<RectangularPixel> roiPixel(det->regionOfInterestPixel());
-        return new ImageCoords(detector->axesClippedToRegionOfInterest(), *roiPixel, beam());
+        return new ImageCoords(detector->axesClippedToRegionOfInterest(), *roiPixel,
+                               beam().direction(),
+                               beam().wavelength());
     }
     ASSERT(0);
 }
diff --git a/GUI/Models/InstrumentItems.cpp b/GUI/Models/InstrumentItems.cpp
index e8a6005df80..d07d30d2494 100644
--- a/GUI/Models/InstrumentItems.cpp
+++ b/GUI/Models/InstrumentItems.cpp
@@ -454,11 +454,12 @@ ICoordSystem* OffSpecularInstrumentItem::createCoordSystem() const
 
     if (const auto* rectDetector = dynamic_cast<const RectangularDetector*>(detector2d)) {
         std::unique_ptr<RectangularPixel> detectorPixel(rectDetector->regionOfInterestPixel());
-        return OffSpecularCoordinates::createForRectangularDetector(beam, *alphaAxis,
+        return OffSpecularCoordinates::createForRectangularDetector(beam.direction(), *alphaAxis,
                                                                     *detectorPixel, yAxis);
     }
     if (dynamic_cast<const SphericalDetector*>(detector2d))
-        return OffSpecularCoordinates::createForSphericalDetector(beam, *alphaAxis, yAxis);
+        return OffSpecularCoordinates::createForSphericalDetector(beam.direction(),
+                                                                  *alphaAxis, yAxis);
 
     ASSERT(0);
 }
diff --git a/Tests/UnitTests/Core/Core/DepthProbeConverterTest.cpp b/Tests/UnitTests/Core/Core/DepthProbeConverterTest.cpp
index 55e66b413df..d39a94cece7 100644
--- a/Tests/UnitTests/Core/Core/DepthProbeConverterTest.cpp
+++ b/Tests/UnitTests/Core/Core/DepthProbeConverterTest.cpp
@@ -95,13 +95,15 @@ void DepthProbeCoordinatesTest::checkZAxis(Axes::Coords units,
 
 TEST_F(DepthProbeCoordinatesTest, DepthProbeCoordinates)
 {
-    DepthProbeCoordinates converter(m_beam, m_inclination_axis, m_z_axis);
+    DepthProbeCoordinates converter(m_beam.direction(), m_beam.wavelength(),
+                                    m_inclination_axis, m_z_axis);
     checkMainFunctionality(converter);
 }
 
 TEST_F(DepthProbeCoordinatesTest, DepthProbeCoordinatesExceptions)
 {
-    DepthProbeCoordinates converter(m_beam, m_inclination_axis, m_z_axis);
+    DepthProbeCoordinates converter(m_beam.direction(), m_beam.wavelength(),
+                                    m_inclination_axis, m_z_axis);
 
     EXPECT_THROW(converter.axisName(0, Axes::Coords::MM), std::runtime_error);
     EXPECT_THROW(converter.axisName(1, Axes::Coords::MM), std::runtime_error);
@@ -122,7 +124,8 @@ TEST_F(DepthProbeCoordinatesTest, DepthProbeCoordinatesExceptions)
 
 TEST_F(DepthProbeCoordinatesTest, DepthProbeCoordinatesClone)
 {
-    DepthProbeCoordinates converter(m_beam, m_inclination_axis, m_z_axis);
+    DepthProbeCoordinates converter(m_beam.direction(), m_beam.wavelength(),
+                                    m_inclination_axis, m_z_axis);
     std::unique_ptr<DepthProbeCoordinates> converter_clone(converter.clone());
     checkMainFunctionality(*converter_clone);
 }
diff --git a/Tests/UnitTests/Core/Instrument/OffSpecularConverterTest.cpp b/Tests/UnitTests/Core/Instrument/OffSpecularConverterTest.cpp
index 36d5faa094b..838752a95ce 100644
--- a/Tests/UnitTests/Core/Instrument/OffSpecularConverterTest.cpp
+++ b/Tests/UnitTests/Core/Instrument/OffSpecularConverterTest.cpp
@@ -13,7 +13,8 @@ public:
         const auto axes = m_detector.axesClippedToRegionOfInterest();
         const IAxis& yAxis = *axes[1];
 
-        return OffSpecularCoordinates::createForSphericalDetector(m_beam, m_alpha_i_axis, yAxis);
+        return OffSpecularCoordinates::createForSphericalDetector(m_beam.direction(),
+                                                                  m_alpha_i_axis, yAxis);
     }
 
 protected:
diff --git a/Tests/UnitTests/Core/Instrument/RectangularConverterTest.cpp b/Tests/UnitTests/Core/Instrument/RectangularConverterTest.cpp
index 799bc663e6e..1d7389f3830 100644
--- a/Tests/UnitTests/Core/Instrument/RectangularConverterTest.cpp
+++ b/Tests/UnitTests/Core/Instrument/RectangularConverterTest.cpp
@@ -42,7 +42,8 @@ ImageCoordsTest::ImageCoordsTest()
 TEST_F(ImageCoordsTest, ImageCoords)
 {
     std::unique_ptr<RectangularPixel> roiPixel(m_detector.regionOfInterestPixel());
-    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel, m_beam);
+    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel,
+                          m_beam.direction(), m_beam.wavelength());
 
     EXPECT_EQ(converter.dimension(), 2u);
 
@@ -101,7 +102,8 @@ TEST_F(ImageCoordsTest, ImageCoords)
 TEST_F(ImageCoordsTest, ImageCoordsClone)
 {
     std::unique_ptr<RectangularPixel> roiPixel(m_detector.regionOfInterestPixel());
-    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel, m_beam);
+    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel,
+                          m_beam.direction(), m_beam.wavelength());
     std::unique_ptr<ImageCoords> P_clone(converter.clone());
 
     EXPECT_EQ(P_clone->dimension(), 2u);
@@ -153,7 +155,8 @@ TEST_F(ImageCoordsTest, ImageCoordsWithROI)
 
     m_detector.setRegionOfInterest(roi_xmin, roi_ymin, roi_xmax, roi_ymax);
     std::unique_ptr<RectangularPixel> roiPixel(m_detector.regionOfInterestPixel());
-    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel, m_beam);
+    ImageCoords converter(m_detector.axesClippedToRegionOfInterest(), *roiPixel,
+                          m_beam.direction(), m_beam.wavelength());
 
     EXPECT_EQ(converter.calculateMin(0, Axes::Coords::UNDEFINED), 100);
     EXPECT_EQ(converter.calculateMax(0, Axes::Coords::UNDEFINED), 152);
diff --git a/Tests/UnitTests/Core/Instrument/SphericalConverterTest.cpp b/Tests/UnitTests/Core/Instrument/SphericalConverterTest.cpp
index 62db703712c..673b9b294b4 100644
--- a/Tests/UnitTests/Core/Instrument/SphericalConverterTest.cpp
+++ b/Tests/UnitTests/Core/Instrument/SphericalConverterTest.cpp
@@ -28,7 +28,8 @@ SphericalCoordsTest::SphericalCoordsTest()
 
 TEST_F(SphericalCoordsTest, SphericalCoords)
 {
-    SphericalCoords converter(m_detector.axesClippedToRegionOfInterest(), m_beam);
+    SphericalCoords converter(m_detector.axesClippedToRegionOfInterest(), m_beam.direction(),
+                              m_beam.wavelength());
 
     EXPECT_EQ(converter.dimension(), 2u);
 
@@ -80,7 +81,8 @@ TEST_F(SphericalCoordsTest, SphericalCoords)
 
 TEST_F(SphericalCoordsTest, SphericalCoordsClone)
 {
-    SphericalCoords converter(m_detector.axesClippedToRegionOfInterest(), m_beam);
+    SphericalCoords converter(m_detector.axesClippedToRegionOfInterest(),
+                              m_beam.direction(), m_beam.wavelength());
     std::unique_ptr<SphericalCoords> P_clone(converter.clone());
 
     EXPECT_EQ(P_clone->dimension(), 2u);
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index 6c3b4bdcdcf..f2e946cb9be 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -291,7 +291,7 @@ Interface for objects that provide axis translations to different units for  IDe
 C++ includes: CoordSystem2D.h
 ";
 
-%feature("docstring")  CoordSystem2D::CoordSystem2D "CoordSystem2D::CoordSystem2D(const Beam &beam)
+%feature("docstring")  CoordSystem2D::CoordSystem2D "CoordSystem2D::CoordSystem2D(const Direction &direction, double wavelength=0)
 ";
 
 %feature("docstring")  CoordSystem2D::~CoordSystem2D "CoordSystem2D::~CoordSystem2D() override=default
@@ -368,7 +368,7 @@ DepthProbeCoordinates class handles the unit translations for depth probe simula
 C++ includes: CoordSystem2D.h
 ";
 
-%feature("docstring")  DepthProbeCoordinates::DepthProbeCoordinates "DepthProbeCoordinates::DepthProbeCoordinates(const Beam &beam, const IAxis &alpha_axis, const IAxis &z_axis)
+%feature("docstring")  DepthProbeCoordinates::DepthProbeCoordinates "DepthProbeCoordinates::DepthProbeCoordinates(const Direction &direction, double wavelength, const IAxis &alpha_axis, const IAxis &z_axis)
 ";
 
 %feature("docstring")  DepthProbeCoordinates::~DepthProbeCoordinates "DepthProbeCoordinates::~DepthProbeCoordinates() override
@@ -1533,7 +1533,7 @@ ICoordSystem class that handles the unit translations for rectangular detectors
 C++ includes: CoordSystem2D.h
 ";
 
-%feature("docstring")  ImageCoords::ImageCoords "ImageCoords::ImageCoords(const CloneableVector< IAxis > &axes, const RectangularPixel &regionOfInterestPixel, const Beam &beam)
+%feature("docstring")  ImageCoords::ImageCoords "ImageCoords::ImageCoords(const CloneableVector< IAxis > &axes, const RectangularPixel &regionOfInterestPixel, const Direction &direction, double wavelength)
 ";
 
 %feature("docstring")  ImageCoords::~ImageCoords "ImageCoords::~ImageCoords() override
@@ -2661,7 +2661,7 @@ ICoordSystem class that handles the unit translations for spherical detectors It
 C++ includes: CoordSystem2D.h
 ";
 
-%feature("docstring")  SphericalCoords::SphericalCoords "SphericalCoords::SphericalCoords(const CloneableVector< IAxis > &axes, const Beam &beam)
+%feature("docstring")  SphericalCoords::SphericalCoords "SphericalCoords::SphericalCoords(const CloneableVector< IAxis > &axes, const Direction &direction, double wavelength)
 ";
 
 %feature("docstring")  SphericalCoords::~SphericalCoords "SphericalCoords::~SphericalCoords() override
-- 
GitLab