diff --git a/Core/Computation/SpecularComputation.cpp b/Core/Computation/SpecularComputation.cpp index 4ca59e5f8b52d77c7b96613507d642768c889592..e618d639823ebe9a0457796a4d2a32f11cab3844 100644 --- a/Core/Computation/SpecularComputation.cpp +++ b/Core/Computation/SpecularComputation.cpp @@ -17,7 +17,7 @@ #include "Core/Computation/ProgressHandler.h" #include "Core/Computation/SpecularComputationTerm.h" #include "Core/Computation/SpecularStrategyBuilder.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" static_assert(std::is_copy_constructible<SpecularComputation>::value == false, "SpecularComputation should not be copy constructible"); diff --git a/Core/Computation/SpecularComputationTerm.cpp b/Core/Computation/SpecularComputationTerm.cpp index 4c13503146756adaa9dace45582a81f6954dc302..a6bb6ead90bdc3be76d1c9b92ef426a15b31ccca 100644 --- a/Core/Computation/SpecularComputationTerm.cpp +++ b/Core/Computation/SpecularComputationTerm.cpp @@ -15,7 +15,7 @@ #include "Core/Computation/SpecularComputationTerm.h" #include "Core/Computation/DelayedProgressCounter.h" #include "Sample/RT/ILayerRTCoefficients.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" // ************************************************************************** // // class SpecularComputationTerm diff --git a/Core/Scan/AngularSpecScan.cpp b/Core/Scan/AngularSpecScan.cpp index 68ec62c154cbfcb630488c47bd211ea3b31fa9fc..c89d8566509ecd4957bcc6ec76b850b499aa5069 100644 --- a/Core/Scan/AngularSpecScan.cpp +++ b/Core/Scan/AngularSpecScan.cpp @@ -19,7 +19,7 @@ #include "Device/Beam/IFootprintFactor.h" #include "Device/Resolution/ScanResolution.h" #include "Param/Distrib/RangedDistributions.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" namespace { @@ -79,7 +79,8 @@ AngularSpecScan* AngularSpecScan::clone() const AngularSpecScan::~AngularSpecScan() = default; -std::vector<SpecularSimulationElement> AngularSpecScan::generateSimulationElements() const +std::vector<SpecularSimulationElement> +AngularSpecScan::generateSimulationElements(const Instrument& instrument) const { const auto wls = extractValues(applyWlResolution(), [](const ParameterSample& sample) { return sample.value; }); @@ -93,8 +94,8 @@ std::vector<SpecularSimulationElement> AngularSpecScan::generateSimulationElemen const double inc = incs[i][k]; for (size_t j = 0, size_wls = wls[i].size(); j < size_wls; ++j) { const double wl = wls[i][j]; - result.emplace_back( - SpecularSimulationElement(wl, -inc, wl >= 0 && inc >= 0 && inc <= M_PI_2)); + result.emplace_back(SpecularSimulationElement( + wl, -inc, instrument, wl >= 0 && inc >= 0 && inc <= M_PI_2)); } } } diff --git a/Core/Scan/AngularSpecScan.h b/Core/Scan/AngularSpecScan.h index 1cfe3b6c532c06da0a1969e5a0499321bcc179d8..5ccb3e12b140a160095c64f216cbc3d4aea9f26f 100644 --- a/Core/Scan/AngularSpecScan.h +++ b/Core/Scan/AngularSpecScan.h @@ -40,7 +40,8 @@ public: #ifndef SWIG //! Generates simulation elements for specular simulations - std::vector<SpecularSimulationElement> generateSimulationElements() const override; + std::vector<SpecularSimulationElement> + generateSimulationElements(const Instrument& instrument) const override; //! Returns coordinate axis assigned to the data holder virtual const IAxis* coordinateAxis() const override { return m_inc_angle.get(); } diff --git a/Core/Scan/ISpecularScan.h b/Core/Scan/ISpecularScan.h index c68d3b7613b17ba78f5b088668be7ac2b9c90eef..9093d0b4da3fac8b91311ae9b73b0bc665a100f3 100644 --- a/Core/Scan/ISpecularScan.h +++ b/Core/Scan/ISpecularScan.h @@ -23,6 +23,7 @@ class IAxis; class IFootprintFactor; +class Instrument; class SpecularSimulationElement; //! Pure virtual base class for all types of specular scans. @@ -34,7 +35,8 @@ public: #ifndef SWIG //! Generates simulation elements for specular simulations - virtual std::vector<SpecularSimulationElement> generateSimulationElements() const = 0; + virtual std::vector<SpecularSimulationElement> + generateSimulationElements(const Instrument& instrument) const = 0; //! Returns coordinate axis assigned to the data holder virtual const IAxis* coordinateAxis() const = 0; diff --git a/Core/Scan/QSpecScan.cpp b/Core/Scan/QSpecScan.cpp index 4c660be8a462bfea2a65151cbc605cdf4634998a..21656e7f4cf92e9615550f5ead49d5dddcc4c514 100644 --- a/Core/Scan/QSpecScan.cpp +++ b/Core/Scan/QSpecScan.cpp @@ -18,7 +18,7 @@ #include "Base/Utils/PyFmt.h" #include "Device/Resolution/ScanResolution.h" #include "Param/Distrib/RangedDistributions.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" QSpecScan::QSpecScan(std::vector<double> qs_nm) : m_qs(std::make_unique<PointwiseAxis>("qs", std::move(qs_nm))), @@ -50,14 +50,15 @@ QSpecScan* QSpecScan::clone() const } //! Generates simulation elements for specular simulations -std::vector<SpecularSimulationElement> QSpecScan::generateSimulationElements() const +std::vector<SpecularSimulationElement> +QSpecScan::generateSimulationElements(const Instrument& instrument) const { const std::vector<double> qz = generateQzVector(); std::vector<SpecularSimulationElement> result; result.reserve(qz.size()); for (size_t i = 0, size = qz.size(); i < size; ++i) - result.emplace_back(SpecularSimulationElement(-qz[i] / 2.0, qz[i] >= 0)); + result.emplace_back(SpecularSimulationElement(-qz[i] / 2.0, instrument, qz[i] >= 0)); return result; } diff --git a/Core/Scan/QSpecScan.h b/Core/Scan/QSpecScan.h index 58a186ac4b606c75d32872a591f06c08a5baf300..768d33ec85b3e6fc219bc31625754d036c8ecb00 100644 --- a/Core/Scan/QSpecScan.h +++ b/Core/Scan/QSpecScan.h @@ -42,7 +42,8 @@ public: #ifndef SWIG //! Generates simulation elements for specular simulations - std::vector<SpecularSimulationElement> generateSimulationElements() const override; + std::vector<SpecularSimulationElement> + generateSimulationElements(const Instrument& instrument) const override; //! Returns coordinate axis assigned to the data holder virtual const IAxis* coordinateAxis() const override { return m_qs.get(); } diff --git a/Sample/Slice/SpecularSimulationElement.cpp b/Core/Scan/SpecularSimulationElement.cpp similarity index 64% rename from Sample/Slice/SpecularSimulationElement.cpp rename to Core/Scan/SpecularSimulationElement.cpp index 5868be2d9651795e864ec177eb0a5894ad21f2cb..a1de5e7f48f9e00c591ee752f9351900b8397031 100644 --- a/Sample/Slice/SpecularSimulationElement.cpp +++ b/Core/Scan/SpecularSimulationElement.cpp @@ -2,7 +2,7 @@ // // BornAgain: simulate and fit scattering at grazing incidence // -//! @file Sample/Slice/SpecularSimulationElement.cpp +//! @file Core/Scan/SpecularSimulationElement.cpp //! @brief Implements the class SpecularSimulationElement. //! //! @homepage http://www.bornagainproject.org @@ -12,11 +12,16 @@ // // ************************************************************************** // -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" +#include "Device/Detector/IDetector.h" +#include "Device/Instrument/Instrument.h" #include "Sample/Slice/KzComputation.h" -SpecularSimulationElement::SpecularSimulationElement(double kz, bool computable) - : m_intensity(0.0), m_computable(computable), +SpecularSimulationElement::SpecularSimulationElement(double kz, + const Instrument& instrument, bool computable) + : m_polarization(instrument.getBeam().getPolarization(), + instrument.detector().detectionProperties().analyzerOperator()), + m_intensity(0.0), m_computable(computable), m_kz_computation([kz](const std::vector<Slice>& slices) { return KzComputation::computeKzFromSLDs(slices, kz); }) @@ -24,8 +29,10 @@ SpecularSimulationElement::SpecularSimulationElement(double kz, bool computable) } SpecularSimulationElement::SpecularSimulationElement(double wavelength, double alpha, - bool computable) - : m_intensity(0.0), m_computable(computable), + const Instrument& instrument, bool computable) + : m_polarization(instrument.getBeam().getPolarization(), + instrument.detector().detectionProperties().analyzerOperator()), + m_intensity(0.0), m_computable(computable), m_kz_computation( [k = vecOfLambdaAlphaPhi(wavelength, alpha, 0.0)](const std::vector<Slice>& slices) { return KzComputation::computeKzFromRefIndices(slices, k); @@ -47,29 +54,7 @@ SpecularSimulationElement::SpecularSimulationElement(SpecularSimulationElement&& SpecularSimulationElement::~SpecularSimulationElement() = default; -SpecularSimulationElement& -SpecularSimulationElement::operator=(const SpecularSimulationElement& other) -{ - if (this != &other) { - SpecularSimulationElement tmp(other); - tmp.swapContent(*this); - } - return *this; -} - -void SpecularSimulationElement::setPolarizationHandler(const PolarizationHandler& handler) -{ - m_polarization = handler; -} - std::vector<complex_t> SpecularSimulationElement::produceKz(const std::vector<Slice>& slices) { return m_kz_computation(slices); } - -void SpecularSimulationElement::swapContent(SpecularSimulationElement& other) -{ - m_polarization.swapContent(other.m_polarization); - std::swap(m_intensity, other.m_intensity); - m_kz_computation.swap(other.m_kz_computation); -} diff --git a/Sample/Slice/SpecularSimulationElement.h b/Core/Scan/SpecularSimulationElement.h similarity index 79% rename from Sample/Slice/SpecularSimulationElement.h rename to Core/Scan/SpecularSimulationElement.h index c3c31758700f608b5d12841a6fac8cc62739e4af..88d06d5dc034695c6739513a701037a041b5d021 100644 --- a/Sample/Slice/SpecularSimulationElement.h +++ b/Core/Scan/SpecularSimulationElement.h @@ -2,7 +2,7 @@ // // BornAgain: simulate and fit scattering at grazing incidence // -//! @file Sample/Slice/SpecularSimulationElement.h +//! @file Core/Scan/SpecularSimulationElement.h //! @brief Declares the class SpecularSimulationElement. //! //! @homepage http://www.bornagainproject.org @@ -21,6 +21,7 @@ #include <memory> #include <vector> +class Instrument; class Slice; //! Data stucture containing both input and output of a single image pixel for specular simulation. @@ -29,18 +30,16 @@ class Slice; class SpecularSimulationElement { public: - SpecularSimulationElement(double kz, bool computable); - SpecularSimulationElement(double wavelength, double alpha, bool computable); + SpecularSimulationElement(double kz, const Instrument& instrument, bool computable); + SpecularSimulationElement(double wavelength, double alpha, const Instrument& instrument, + bool computable); SpecularSimulationElement(const SpecularSimulationElement& other); SpecularSimulationElement(SpecularSimulationElement&& other) noexcept; ~SpecularSimulationElement(); - SpecularSimulationElement& operator=(const SpecularSimulationElement& other); - - //! Assigns PolarizationHandler. - void setPolarizationHandler(const PolarizationHandler& handler); + SpecularSimulationElement& operator=(const SpecularSimulationElement& other) = delete; //! Returns assigned PolarizationHandler. const PolarizationHandler& polarizationHandler() const { return m_polarization; } @@ -55,12 +54,10 @@ public: std::vector<complex_t> produceKz(const std::vector<Slice>& slices); private: - void swapContent(SpecularSimulationElement& other); - - PolarizationHandler m_polarization; + const PolarizationHandler m_polarization; double m_intensity; //!< simulated intensity for detector cell const bool m_computable; - std::function<std::vector<complex_t>(const std::vector<Slice>&)> m_kz_computation; + const std::function<std::vector<complex_t>(const std::vector<Slice>&)> m_kz_computation; }; #endif // BORNAGAIN_CORE_MULTILAYER_SPECULARSIMULATIONELEMENT_H diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp index facfe31ac45a9409331531f93b21f9508831508e..282aab9c1bfa81f2d6cd8c4dd39d29e0e021b3bc 100644 --- a/Core/Simulation/SpecularSimulation.cpp +++ b/Core/Simulation/SpecularSimulation.cpp @@ -24,7 +24,7 @@ #include "Param/Base/ParameterPool.h" #include "Param/Base/RealParameter.h" #include "Param/Distrib/Distributions.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" namespace { @@ -47,22 +47,11 @@ std::unique_ptr<AngularSpecScan> mangledScan(const AngularSpecScan& scan, const std::vector<SpecularSimulationElement> generateSimulationElements(const Instrument& instrument, const ISpecularScan& scan) { - std::vector<SpecularSimulationElement> result; - - // TODO: remove if-else statement when pointwise resolution is implemented + // TODO: remove if statement when pointwise resolution is implemented if (const auto* aScan = dynamic_cast<const AngularSpecScan*>(&scan)) - result = mangledScan(*aScan, instrument.getBeam())->generateSimulationElements(); - else - result = scan.generateSimulationElements(); - - // add polarization and analyzer operators - const auto& polarization = instrument.getBeam().getPolarization(); - const auto& analyzer = instrument.detector().detectionProperties().analyzerOperator(); + return mangledScan(*aScan, instrument.getBeam())->generateSimulationElements(instrument); - for (auto& elem : result) - elem.setPolarizationHandler({polarization, analyzer}); - - return result; + return scan.generateSimulationElements(instrument); } } // namespace diff --git a/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp b/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp index 01ef3a21f80b932564f18b65b7ff76de75782b20..3202c2ddfbd90fb5e966b24da263905e4104c388 100644 --- a/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp +++ b/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp @@ -3,9 +3,10 @@ #include "Core/Scan/AngularSpecScan.h" #include "Core/Scan/QSpecScan.h" #include "Device/Beam/FootprintGauss.h" +#include "Device/Instrument/Instrument.h" #include "Device/Resolution/ScanResolution.h" #include "Param/Distrib/RangedDistributions.h" -#include "Sample/Slice/SpecularSimulationElement.h" +#include "Core/Scan/SpecularSimulationElement.h" #include "Tests/GTestWrapper/google_test.h" class SpecularScanTest : public ::testing::Test @@ -184,14 +185,17 @@ TEST_F(SpecularScanTest, QScanClone) TEST_F(SpecularScanTest, GenerateSimElements) { AngularSpecScan scan(0.1, std::vector<double>{0.0, 0.2, 0.3}); - std::vector<SpecularSimulationElement> sim_elements = scan.generateSimulationElements(); + const Instrument instrument; + std::vector<SpecularSimulationElement> sim_elements = + scan.generateSimulationElements(instrument); EXPECT_EQ(sim_elements.size(), scan.numberOfSimulationElements()); EXPECT_EQ(scan.numberOfSimulationElements(), 3u); for (size_t i = 0; i < sim_elements.size(); ++i) EXPECT_TRUE(sim_elements[i].isCalculated()); QSpecScan scan2(std::vector<double>{0.0, 0.2, 0.3}); - std::vector<SpecularSimulationElement> sim_elements2 = scan.generateSimulationElements(); + std::vector<SpecularSimulationElement> sim_elements2 = + scan.generateSimulationElements(instrument); EXPECT_EQ(sim_elements2.size(), scan2.numberOfSimulationElements()); EXPECT_EQ(scan2.numberOfSimulationElements(), 3u); for (size_t i = 0; i < sim_elements2.size(); ++i) diff --git a/auto/Wrap/doxygenCore.i b/auto/Wrap/doxygenCore.i index bfa00895e7a5fe63854c63ea53e2ebbfab75018f..45fe2b67a10ddc37dd93b9a303bb4c7aaf972aec 100644 --- a/auto/Wrap/doxygenCore.i +++ b/auto/Wrap/doxygenCore.i @@ -26,7 +26,7 @@ Sets angle-defined specular scan. The first parameter is always a wavelength in %feature("docstring") AngularSpecScan::clone "AngularSpecScan * AngularSpecScan::clone() const override "; -%feature("docstring") AngularSpecScan::generateSimulationElements "std::vector< SpecularSimulationElement > AngularSpecScan::generateSimulationElements() const override +%feature("docstring") AngularSpecScan::generateSimulationElements "std::vector< SpecularSimulationElement > AngularSpecScan::generateSimulationElements(const Instrument &instrument) const override Generates simulation elements for specular simulations. "; @@ -915,7 +915,7 @@ C++ includes: ISpecularScan.h %feature("docstring") ISpecularScan::clone "ISpecularScan* ISpecularScan::clone() const override=0 "; -%feature("docstring") ISpecularScan::generateSimulationElements "virtual std::vector<SpecularSimulationElement> ISpecularScan::generateSimulationElements() const =0 +%feature("docstring") ISpecularScan::generateSimulationElements "virtual std::vector<SpecularSimulationElement> ISpecularScan::generateSimulationElements(const Instrument &instrument) const =0 Generates simulation elements for specular simulations. "; @@ -1578,7 +1578,7 @@ Sets q-defined specular scan. Accepts either numpy array of q-values sorted in a %feature("docstring") QSpecScan::clone "QSpecScan * QSpecScan::clone() const override "; -%feature("docstring") QSpecScan::generateSimulationElements "std::vector< SpecularSimulationElement > QSpecScan::generateSimulationElements() const override +%feature("docstring") QSpecScan::generateSimulationElements "std::vector< SpecularSimulationElement > QSpecScan::generateSimulationElements(const Instrument &instrument) const override Generates simulation elements for specular simulations. "; @@ -2344,6 +2344,51 @@ Returns internal data handler. "; +// File: classSpecularSimulationElement.xml +%feature("docstring") SpecularSimulationElement " + +Data stucture containing both input and output of a single image pixel for specular simulation. + +C++ includes: SpecularSimulationElement.h +"; + +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double kz, const Instrument &instrument, bool computable) +"; + +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double wavelength, double alpha, const Instrument &instrument, bool computable) +"; + +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(const SpecularSimulationElement &other) +"; + +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(SpecularSimulationElement &&other) noexcept +"; + +%feature("docstring") SpecularSimulationElement::~SpecularSimulationElement "SpecularSimulationElement::~SpecularSimulationElement() +"; + +%feature("docstring") SpecularSimulationElement::polarizationHandler "const PolarizationHandler& SpecularSimulationElement::polarizationHandler() const + +Returns assigned PolarizationHandler. +"; + +%feature("docstring") SpecularSimulationElement::getIntensity "double SpecularSimulationElement::getIntensity() const +"; + +%feature("docstring") SpecularSimulationElement::setIntensity "void SpecularSimulationElement::setIntensity(double intensity) +"; + +%feature("docstring") SpecularSimulationElement::isCalculated "bool SpecularSimulationElement::isCalculated() const + +Returns calculation flag (if it's false, zero intensity is assigned to the element) +"; + +%feature("docstring") SpecularSimulationElement::produceKz "std::vector< complex_t > SpecularSimulationElement::produceKz(const std::vector< Slice > &slices) + +Returns kz values for Abeles computation of reflection/transition coefficients. +"; + + // File: classSpecularStrategyBuilder.xml %feature("docstring") SpecularStrategyBuilder ""; @@ -2459,6 +2504,9 @@ Returns default units to convert to. "; +// File: namespace_0d100.xml + + // File: namespace_0d29.xml @@ -2495,16 +2543,13 @@ Returns default units to convert to. // File: namespace_0d75.xml -// File: namespace_0d80.xml - - // File: namespace_0d82.xml -// File: namespace_0d90.xml +// File: namespace_0d84.xml -// File: namespace_0d96.xml +// File: namespace_0d92.xml // File: namespace_0d98.xml @@ -3048,6 +3093,12 @@ Generate z values (equidistant) for use in MaterialProfile. // File: QSpecScan_8h.xml +// File: SpecularSimulationElement_8cpp.xml + + +// File: SpecularSimulationElement_8h.xml + + // File: UnitConverter1D_8cpp.xml diff --git a/auto/Wrap/doxygenSample.i b/auto/Wrap/doxygenSample.i index 3318ee252af6df42e029123cf50e4233ca3671be..68d8e4891a8c70a869516dd4923aac2ba6774e5d 100644 --- a/auto/Wrap/doxygenSample.i +++ b/auto/Wrap/doxygenSample.i @@ -7489,10 +7489,10 @@ Data stucture containing both input and output of a single image pixel for specu C++ includes: SpecularSimulationElement.h "; -%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double kz, bool computable) +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double kz, bool computable, const Instrument &instrument) "; -%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double wavelength, double alpha, bool computable) +%feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(double wavelength, double alpha, bool computable, const Instrument &instrument) "; %feature("docstring") SpecularSimulationElement::SpecularSimulationElement "SpecularSimulationElement::SpecularSimulationElement(const SpecularSimulationElement &other)