From c9f8e7f2a072250bd4d8c94c46ecd89bfe63ccc2 Mon Sep 17 00:00:00 2001
From: Dmitry Yurov <d.yurov@fz-juelich.de>
Date: Mon, 6 May 2019 14:44:18 +0200
Subject: [PATCH] Replace numberOfSimulationElements with intensityMapSize
 outside of Simulation class tree

Simulation::numberOfSimulationElements was previously used as a synonym
to the number of values in the intensity map. However it is different
in the case of SpecularSimulation with beam divergence and could lead
to malfunctioning in the future. To avoid confusion,
numberOfSimulationElements method was placed in the
protected scope of Simulation class. Simulation::intensityMapSize returns
the actual size of intensity map.
---
 Core/Fitting/SimDataPair.cpp                       |  2 +-
 Core/Simulation/DepthProbeSimulation.h             |  8 ++++++--
 Core/Simulation/GISASSimulation.h                  |  6 +++---
 Core/Simulation/OffSpecSimulation.h                |  6 +++---
 Core/Simulation/Simulation.h                       |  6 +++++-
 Core/Simulation/Simulation2D.h                     |  5 ++++-
 Core/Simulation/SpecularSimulation.cpp             |  5 +++++
 Core/Simulation/SpecularSimulation.h               |  8 ++++++--
 Tests/UnitTests/Core/Other/GISASSimulationTest.cpp | 10 +++++-----
 9 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/Core/Fitting/SimDataPair.cpp b/Core/Fitting/SimDataPair.cpp
index bc3936a1a15..43269a26ff8 100644
--- a/Core/Fitting/SimDataPair.cpp
+++ b/Core/Fitting/SimDataPair.cpp
@@ -149,7 +149,7 @@ void SimDataPair::create_simulation(const Fit::Parameters& params)
     m_simulation = m_simulation_builder(params);
 
     if (m_fit_elements_count == 0) {
-        m_fit_elements_count = m_simulation->numberOfSimulationElements();
+        m_fit_elements_count = m_simulation->intensityMapSize();
         m_experimental_data = IntensityDataFunctions::ConvertData(*m_simulation, *m_data, false);
 
         m_experimental_array.clear();
diff --git a/Core/Simulation/DepthProbeSimulation.h b/Core/Simulation/DepthProbeSimulation.h
index 301426dd332..3fa8ca5ecff 100644
--- a/Core/Simulation/DepthProbeSimulation.h
+++ b/Core/Simulation/DepthProbeSimulation.h
@@ -29,8 +29,6 @@ public:
 
     void accept(INodeVisitor* visitor) const override final {visitor->visit(this);}
 
-    size_t numberOfSimulationElements() const override;
-
     //! Returns the results of the simulation in a format that supports unit conversion and export
     //! to numpy arrays
     SimulationResult result() const override;
@@ -49,6 +47,9 @@ public:
     //! Returns a pointer to z-position axis.
     const IAxis* getZAxis() const;
 
+    //! Returns the total number of the intensity values in the simulation result
+    size_t intensityMapSize() const override { return numberOfSimulationElements(); }
+
 #ifndef SWIG
     std::unique_ptr<IUnitConverter> createUnitConverter() const;
 #endif
@@ -63,6 +64,9 @@ private:
     //! Initializes the vector of Simulation elements
     void initSimulationElementVector() override;
 
+    //! Gets the number of elements this simulation needs to calculate
+    size_t numberOfSimulationElements() const override;
+
     //! Generate simulation elements for given beam
     std::vector<DepthProbeElement> generateSimulationElements(const Beam& beam);
 
diff --git a/Core/Simulation/GISASSimulation.h b/Core/Simulation/GISASSimulation.h
index 4e6c37b1701..d01ed59748e 100644
--- a/Core/Simulation/GISASSimulation.h
+++ b/Core/Simulation/GISASSimulation.h
@@ -40,9 +40,6 @@ public:
     //! Put into a clean state for running a simulation
     void prepareSimulation() override;
 
-    //! Gets the number of elements this simulation needs to calculate
-    size_t numberOfSimulationElements() const override;
-
     //! Returns the results of the simulation in a format that supports unit conversion and export
     //! to numpy arrays
     SimulationResult result() const override;
@@ -56,6 +53,9 @@ private:
     //! Initializes the vector of Simulation elements
     void initSimulationElementVector() override;
 
+    //! Gets the number of elements this simulation needs to calculate
+    size_t numberOfSimulationElements() const override;
+
     void initialize();
 };
 
diff --git a/Core/Simulation/OffSpecSimulation.h b/Core/Simulation/OffSpecSimulation.h
index 7f0ce9d239c..298652c1628 100644
--- a/Core/Simulation/OffSpecSimulation.h
+++ b/Core/Simulation/OffSpecSimulation.h
@@ -39,9 +39,6 @@ public:
     //! Put into a clean state for running a simulation
     void prepareSimulation() final;
 
-    //! Gets the number of elements this simulation needs to calculate
-    size_t numberOfSimulationElements() const final;
-
     //! Returns the results of the simulation in a format that supports unit conversion and export
     //! to numpy arrays
     SimulationResult result() const override;
@@ -72,6 +69,9 @@ private:
     //! Default implementation only adds the detector axes
     void updateIntensityMap() override;
 
+    //! Gets the number of elements this simulation needs to calculate
+    size_t numberOfSimulationElements() const final;
+
     //! Normalize, apply detector resolution and transfer detector image corresponding to
     //! alpha_i = mp_alpha_i_axis->getBin(index)
     void transferDetectorImage(size_t index);
diff --git a/Core/Simulation/Simulation.h b/Core/Simulation/Simulation.h
index 93ed57b0383..63359b799a5 100644
--- a/Core/Simulation/Simulation.h
+++ b/Core/Simulation/Simulation.h
@@ -77,7 +77,8 @@ public:
     void setBackground(const IBackground& bg);
     const IBackground* background() const { return mP_background.get(); }
 
-    virtual size_t numberOfSimulationElements() const=0;
+    //! Returns the total number of the intensity values in the simulation result
+    virtual size_t intensityMapSize() const = 0;
 
     //! Returns the results of the simulation in a format that supports unit conversion and export
     //! to numpy arrays
@@ -111,6 +112,9 @@ protected:
 
     virtual void updateIntensityMap() {}
 
+    //! Gets the number of elements this simulation needs to calculate
+    virtual size_t numberOfSimulationElements() const = 0;
+
     SampleProvider m_sample_provider;
     SimulationOptions m_options;
     DistributionHandler m_distribution_handler;
diff --git a/Core/Simulation/Simulation2D.h b/Core/Simulation/Simulation2D.h
index e4151c68405..02793681439 100644
--- a/Core/Simulation/Simulation2D.h
+++ b/Core/Simulation/Simulation2D.h
@@ -28,7 +28,7 @@ public:
     Simulation2D() =default;
     Simulation2D(const MultiLayer& p_sample);
     Simulation2D(const std::shared_ptr<IMultiLayerBuilder> p_sample_builder);
-    virtual ~Simulation2D() =default;
+    ~Simulation2D() override = default;
 
     Simulation2D* clone() const override =0;
 
@@ -61,6 +61,9 @@ public:
     //! Sets rectangular region of interest with lower left and upper right corners defined.
     void setRegionOfInterest(double xlow, double ylow, double xup, double yup);
 
+    //! Returns the total number of the intensity values in the simulation result
+    size_t intensityMapSize() const override { return numberOfSimulationElements(); }
+
 protected:
     Simulation2D(const Simulation2D& other);
 
diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp
index 89e80e06992..2fecb740e3d 100644
--- a/Core/Simulation/SpecularSimulation.cpp
+++ b/Core/Simulation/SpecularSimulation.cpp
@@ -122,6 +122,11 @@ const IFootprintFactor* SpecularSimulation::footprintFactor() const
     return m_data_handler->footprintFactor();
 }
 
+size_t SpecularSimulation::intensityMapSize() const
+{
+    return m_data_handler->coordinateAxis()->size();
+}
+
 void SpecularSimulation::initSimulationElementVector()
 {
     const auto& beam = m_instrument.getBeam();
diff --git a/Core/Simulation/SpecularSimulation.h b/Core/Simulation/SpecularSimulation.h
index 96664d4b350..f667dccbbc6 100644
--- a/Core/Simulation/SpecularSimulation.h
+++ b/Core/Simulation/SpecularSimulation.h
@@ -46,8 +46,6 @@ public:
 
     void accept(INodeVisitor* visitor) const override final {visitor->visit(this);}
 
-    size_t numberOfSimulationElements() const override;
-
     //! Returns the results of the simulation in a format that supports unit conversion and export
     //! to numpy arrays. If simulation was not run, returns an array of proper size filled with
     //! zeros.
@@ -62,6 +60,9 @@ public:
     //! Returns a pointer to footprint factor holder
     const IFootprintFactor* footprintFactor() const;
 
+    //! Returns the total number of the intensity values in the simulation result
+    size_t intensityMapSize() const override;
+
 #ifndef SWIG
     //! Returns internal data handler
     const ISpecularScan* dataHandler() const { return m_data_handler.get(); }
@@ -101,6 +102,9 @@ private:
 
     void moveDataFromCache() override;
 
+    //! Gets the number of elements this simulation needs to calculate
+    size_t numberOfSimulationElements() const override;
+
     //! Creates intensity data from simulation elements
     std::unique_ptr<OutputData<double>> createIntensityData() const;
 
diff --git a/Tests/UnitTests/Core/Other/GISASSimulationTest.cpp b/Tests/UnitTests/Core/Other/GISASSimulationTest.cpp
index 42ec0c4dd72..150c649780b 100644
--- a/Tests/UnitTests/Core/Other/GISASSimulationTest.cpp
+++ b/Tests/UnitTests/Core/Other/GISASSimulationTest.cpp
@@ -22,7 +22,7 @@ TEST_F(GISASSimulationTest, SimulationInitialState)
 {
     EXPECT_EQ(BornAgain::GISASSimulationType, m_simulation.getName());
     EXPECT_EQ(nullptr, m_simulation.sample());
-    EXPECT_EQ(0u, m_simulation.numberOfSimulationElements());
+    EXPECT_EQ(0u, m_simulation.intensityMapSize());
     EXPECT_THROW(m_simulation.result(), std::runtime_error);
     EXPECT_EQ(1u, m_simulation.getChildren().size());
 }
@@ -33,14 +33,14 @@ TEST_F(GISASSimulationTest, SimulationConstruction)
     GISASSimulation simulation(multi_layer);
     EXPECT_EQ(BornAgain::GISASSimulationType, simulation.getName());
     EXPECT_NE(nullptr, simulation.sample());
-    EXPECT_EQ(0u, simulation.numberOfSimulationElements());
+    EXPECT_EQ(0u, simulation.intensityMapSize());
     EXPECT_THROW(simulation.result(), std::runtime_error);
     EXPECT_EQ(2u, simulation.getChildren().size());
 
     simulation.setDetectorParameters(10, -2.0, 2.0, 20, 0.0, 2.0);
     EXPECT_EQ(BornAgain::GISASSimulationType, simulation.getName());
     EXPECT_NE(nullptr, simulation.sample());
-    EXPECT_EQ(200u, simulation.numberOfSimulationElements());
+    EXPECT_EQ(200u, simulation.intensityMapSize());
     EXPECT_NO_THROW(simulation.result());
     EXPECT_EQ(2u, simulation.getChildren().size());
 }
@@ -50,7 +50,7 @@ TEST_F(GISASSimulationTest, SimulationClone)
     auto p_clone = m_simulation.clone();
     EXPECT_EQ(BornAgain::GISASSimulationType, p_clone->getName());
     EXPECT_EQ(nullptr, p_clone->sample());
-    EXPECT_EQ(0u, p_clone->numberOfSimulationElements());
+    EXPECT_EQ(0u, p_clone->intensityMapSize());
     EXPECT_THROW(p_clone->result(), std::runtime_error);
     EXPECT_EQ(1u, p_clone->getChildren().size());
     delete p_clone;
@@ -61,7 +61,7 @@ TEST_F(GISASSimulationTest, SimulationClone)
     p_clone = simulation.clone();
     EXPECT_EQ(BornAgain::GISASSimulationType, p_clone->getName());
     EXPECT_NE(nullptr, p_clone->sample());
-    EXPECT_EQ(200u, p_clone->numberOfSimulationElements());
+    EXPECT_EQ(200u, p_clone->intensityMapSize());
     EXPECT_NO_THROW(p_clone->result());
     EXPECT_EQ(2u, p_clone->getChildren().size());
     delete p_clone;
-- 
GitLab