Skip to content
Snippets Groups Projects
Commit 9be457df authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

[jw4] simplify ISimulation2D and IDetector, improve comments ()

Merging branch 'jw4'  into 'main'.

See merge request !1142
parents 6a4aa455 f9384370
No related branches found
No related tags found
1 merge request!1142simplify ISimulation2D and IDetector, improve comments
Pipeline #80209 passed
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/Detector/DetectorContext.cpp
//! @brief Implements DetectorContext class.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Device/Detector/DetectorContext.h"
#include "Device/Detector/IDetector.h"
DetectorContext::DetectorContext(const IDetector* detector)
{
setup_context(detector);
}
size_t DetectorContext::numberOfElements() const
{
return m_active_indices.size();
}
//! Creates pixel for given element index. Element index is sequential index in a vector
//! of DiffuseElements. Corresponds to sequence of detector bins inside ROI and outside
//! of masked areas.
std::unique_ptr<const IPixel> DetectorContext::createPixel(size_t element_index) const
{
return std::unique_ptr<IPixel>(m_pixels[element_index]->clone());
}
size_t DetectorContext::detectorIndex(size_t element_index) const
{
return m_active_indices[element_index];
}
void DetectorContext::setup_context(const IDetector* detector)
{
m_active_indices = detector->active_indices();
m_analyzer_operator = detector->analyzer().matrix();
m_pixels.reserve(m_active_indices.size());
for (auto detector_index : m_active_indices)
m_pixels.emplace_back(detector->createPixel(detector_index));
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/Detector/DetectorContext.h
//! @brief Define DetectorContext class.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#ifndef USER_API
#ifndef BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
#define BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
#include "Base/Pixel/IPixel.h"
#include "Base/Spin/SpinMatrix.h"
#include "Base/Types/OwningVector.h"
#include <memory>
#include <vector>
class IDetector;
//! Holds precalculated information for faster DiffuseElement generation.
//! @ingroup detector
class DetectorContext {
public:
DetectorContext(const IDetector* detector);
DetectorContext(const DetectorContext& other) = delete;
DetectorContext& operator=(const DetectorContext& other) = delete;
size_t numberOfElements() const;
std::unique_ptr<const IPixel> createPixel(size_t element_index) const;
size_t detectorIndex(size_t element_index) const;
private:
void setup_context(const IDetector* detector);
SpinMatrix m_analyzer_operator;
OwningVector<const IPixel> m_pixels; //! All unmasked pixels inside ROI.
std::vector<size_t> m_active_indices; //! The sequence of bin indices (unmasked, in ROI)
};
#endif // BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
#endif // USER_API
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "Base/Const/Units.h" #include "Base/Const/Units.h"
#include "Base/Util/Assert.h" #include "Base/Util/Assert.h"
#include "Device/Beam/Beam.h" #include "Device/Beam/Beam.h"
#include "Device/Detector/DetectorContext.h"
#include "Device/Detector/SimulationAreaIterator.h" #include "Device/Detector/SimulationAreaIterator.h"
#include "Device/Mask/DetectorMask.h" #include "Device/Mask/DetectorMask.h"
#include "Device/Mask/InfinitePlane.h" #include "Device/Mask/InfinitePlane.h"
...@@ -341,11 +340,6 @@ std::vector<size_t> IDetector::active_indices() const ...@@ -341,11 +340,6 @@ std::vector<size_t> IDetector::active_indices() const
return result; return result;
} }
std::unique_ptr<DetectorContext> IDetector::createContext() const
{
return std::make_unique<DetectorContext>(this);
}
void IDetector::addMask(const IShape2D& shape, bool mask_value) void IDetector::addMask(const IShape2D& shape, bool mask_value)
{ {
m_mask->addMask(shape, mask_value); m_mask->addMask(shape, mask_value);
...@@ -365,7 +359,6 @@ const DetectorMask* IDetector::detectorMask() const ...@@ -365,7 +359,6 @@ const DetectorMask* IDetector::detectorMask() const
size_t IDetector::getGlobalIndex(size_t x, size_t y) const size_t IDetector::getGlobalIndex(size_t x, size_t y) const
{ {
if (rank() != 2) ASSERT(rank() == 2);
return totalSize();
return x * axis(1).size() + y; return x * axis(1).size() + y;
} }
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
class Beam; class Beam;
class CoordSystem2D; class CoordSystem2D;
class Datafield; class Datafield;
class DetectorContext;
class DetectorMask; class DetectorMask;
class DiffuseElement; class DiffuseElement;
class Direction; class Direction;
...@@ -36,7 +35,7 @@ class IShape2D; ...@@ -36,7 +35,7 @@ class IShape2D;
class SimulationAreaIterator; class SimulationAreaIterator;
//! Abstract detector interface. //! Abstract base for 2D detectors, realized by RectangularDetector and SphericalDetector.
//! //!
//! Handles also "region of interest" (ROI). In general, the ROI is the whole //! Handles also "region of interest" (ROI). In general, the ROI is the whole
//! detector, and all methods related to ROI work on the whole detector. //! detector, and all methods related to ROI work on the whole detector.
...@@ -170,8 +169,6 @@ public: ...@@ -170,8 +169,6 @@ public:
std::pair<double, double> regionOfInterestBounds(size_t iAxis) const; std::pair<double, double> regionOfInterestBounds(size_t iAxis) const;
#ifndef SWIG #ifndef SWIG
std::unique_ptr<DetectorContext> createContext() const;
//! Create begin-iterator to iterate over all points which are not masked and lay //! Create begin-iterator to iterate over all points which are not masked and lay
//! within the "Region of Interest" //! within the "Region of Interest"
SimulationAreaIterator beginNonMaskedPoints() const; SimulationAreaIterator beginNonMaskedPoints() const;
...@@ -211,25 +208,22 @@ protected: ...@@ -211,25 +208,22 @@ protected:
//! Returns the name for the axis with given index //! Returns the name for the axis with given index
virtual std::string axisName(size_t index) const = 0; virtual std::string axisName(size_t index) const = 0;
//! Return 0 if no ROI has been explicitly set. //! Return number of data points in Roi, or 0 if no Roi is set.
//! Size means number of data points.
virtual size_t sizeOfExplicitRegionOfInterest() const; virtual size_t sizeOfExplicitRegionOfInterest() const;
//! Lower and upper bound of one axis of an explicitly set ROI. //! Returns lower and upper Roi bound of one axis, or (0,0) if no Roi is set.
//! Return 0/0 if no ROI has been explicitly set.
virtual std::pair<double, double> boundsOfExplicitRegionOfInterest(size_t iAxis) const; virtual std::pair<double, double> boundsOfExplicitRegionOfInterest(size_t iAxis) const;
//! Calculate global index from two axis indices //! Returns flattened index computed from two axis indices.
size_t getGlobalIndex(size_t x, size_t y) const; size_t getGlobalIndex(size_t x, size_t y) const;
#ifndef SWIG #ifndef SWIG
//! Keeps RegionOfInterest (ROI) data of one axis //! Keeps RegionOfInterest (ROI) data of one axis.
struct RoiOfAxis { struct RoiOfAxis {
double lower; double lower;
double upper; double upper;
// The following values are all pre-computed values. Aim is to speed up repeated // Precomputed values, to speed up repeated calculations.
// calculations.
size_t lowerIndex; //!< index corresponding to 'lower' size_t lowerIndex; //!< index corresponding to 'lower'
size_t upperIndex; //!< index corresponding to 'upper' size_t upperIndex; //!< index corresponding to 'upper'
size_t roiSize; //!< number of bins on axis of ROI size_t roiSize; //!< number of bins on axis of ROI
......
...@@ -20,15 +20,15 @@ ...@@ -20,15 +20,15 @@
#include "Param/Node/INode.h" #include "Param/Node/INode.h"
#include <heinz/Vectors3D.h> #include <heinz/Vectors3D.h>
class Datafield;
class IBackground; class IBackground;
class IComputation; class IComputation;
class ICoordSystem; class ICoordSystem;
class MultiLayer; class MultiLayer;
class ProgressHandler; class ProgressHandler;
class Datafield; class ReSample;
class SimulationOptions; class SimulationOptions;
class SimulationResult; class SimulationResult;
class ReSample;
//! Abstract base class, holds the infrastructure to run a simulation. //! Abstract base class, holds the infrastructure to run a simulation.
//! //!
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
// ************************************************************************************************ // ************************************************************************************************
#include "Sim/Simulation/ISimulation2D.h" #include "Sim/Simulation/ISimulation2D.h"
#include "Base/Pixel/IPixel.h"
#include "Base/Util/Assert.h" #include "Base/Util/Assert.h"
#include "Device/Beam/Beam.h" #include "Device/Beam/Beam.h"
#include "Device/Detector/DetectorContext.h"
#include "Device/Detector/IDetector.h" #include "Device/Detector/IDetector.h"
#include "Device/Detector/SphericalDetector.h" #include "Device/Detector/SphericalDetector.h"
#include "Resample/Element/DiffuseElement.h" #include "Resample/Element/DiffuseElement.h"
...@@ -50,7 +50,10 @@ std::vector<const INode*> ISimulation2D::nodeChildren() const ...@@ -50,7 +50,10 @@ std::vector<const INode*> ISimulation2D::nodeChildren() const
void ISimulation2D::prepareSimulation() void ISimulation2D::prepareSimulation()
{ {
m_detector_context = m_detector->createContext(); m_active_indices = m_detector->active_indices();
m_pixels.reserve(m_active_indices.size());
for (auto detector_index : m_active_indices)
m_pixels.emplace_back(m_detector->createPixel(detector_index));
} }
void ISimulation2D::addMask(const IShape2D& shape, bool mask_value) void ISimulation2D::addMask(const IShape2D& shape, bool mask_value)
...@@ -70,9 +73,7 @@ void ISimulation2D::setRegionOfInterest(double xlow, double ylow, double xup, do ...@@ -70,9 +73,7 @@ void ISimulation2D::setRegionOfInterest(double xlow, double ylow, double xup, do
size_t ISimulation2D::numberOfElements() const size_t ISimulation2D::numberOfElements() const
{ {
if (!m_detector_context) return m_active_indices.size();
throw std::runtime_error("Error in numberOfElements(): no detector context");
return m_detector_context->numberOfElements();
} }
std::unique_ptr<IComputation> ISimulation2D::createComputation(const ReSample& re_sample, std::unique_ptr<IComputation> ISimulation2D::createComputation(const ReSample& re_sample,
...@@ -92,16 +93,16 @@ std::vector<DiffuseElement> ISimulation2D::generateElements(const Beam& beam) ...@@ -92,16 +93,16 @@ std::vector<DiffuseElement> ISimulation2D::generateElements(const Beam& beam)
const SpinMatrix beam_polMatrices = beam.polMatrix(); const SpinMatrix beam_polMatrices = beam.polMatrix();
const SpinMatrix analyzer_operator = m_detector->analyzer().matrix(); const SpinMatrix analyzer_operator = m_detector->analyzer().matrix();
const size_t spec_index = m_detector->indexOfSpecular(beam); const size_t i_specular = m_detector->indexOfSpecular(beam);
const size_t N = m_detector_context->numberOfElements(); const size_t N = m_active_indices.size();
std::vector<DiffuseElement> result; std::vector<DiffuseElement> result;
result.reserve(N); result.reserve(N);
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
result.emplace_back(DiffuseElement( result.emplace_back(DiffuseElement(
wavelength, alpha_i, phi_i, m_detector_context->createPixel(i), beam_polMatrices, wavelength, alpha_i, phi_i, std::unique_ptr<IPixel>(m_pixels[i]->clone()),
analyzer_operator, m_detector_context->detectorIndex(i) == spec_index)); beam_polMatrices, analyzer_operator, m_active_indices[i] == i_specular));
return result; return result;
} }
......
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
#ifndef BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H #ifndef BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H
#define BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H #define BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H
#include "Base/Types/OwningVector.h"
#include "Sim/Simulation/ISimulation.h" #include "Sim/Simulation/ISimulation.h"
#include <memory>
class Beam; class Beam;
class IDetector; class IDetector;
class DetectorContext;
class DiffuseElement; class DiffuseElement;
class IDetector; class IDetector;
class IPixel;
class IShape2D; class IShape2D;
//! Abstract base class of simulations that generate 2D patterns. //! Abstract base class of simulations that generate 2D patterns.
...@@ -108,8 +108,9 @@ protected: ...@@ -108,8 +108,9 @@ protected:
std::vector<DiffuseElement> m_eles; std::vector<DiffuseElement> m_eles;
private: private:
std::unique_ptr<DetectorContext> m_detector_context; std::vector<size_t> m_active_indices; //!< The sequence of bin indices (unmasked, in ROI)
#endif // SWIG OwningVector<const IPixel> m_pixels; //!< All unmasked pixels inside ROI.
#endif // SWIG
}; };
#endif // BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H #endif // BORNAGAIN_SIM_SIMULATION_ISIMULATION2D_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment