Skip to content
Snippets Groups Projects
Commit 1c212fd9 authored by Matthias Puchner's avatar Matthias Puchner
Browse files

rectify line endings (LF)

parent e981f379
No related branches found
No related tags found
1 merge request!65Refactor Distribution Handling
// ************************************************************************************************ // ************************************************************************************************
// //
// BornAgain: simulate and fit reflection and scattering // BornAgain: simulate and fit reflection and scattering
// //
//! @file Core/Simulation/DepthProbeSimulation.cpp //! @file Core/Simulation/DepthProbeSimulation.cpp
//! @brief Implements class DepthProbeSimulation //! @brief Implements class DepthProbeSimulation
//! //!
//! @homepage http://www.bornagainproject.org //! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING) //! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018 //! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
// //
// ************************************************************************************************ // ************************************************************************************************
#include "Core/Simulation/DepthProbeSimulation.h" #include "Core/Simulation/DepthProbeSimulation.h"
#include "Core/Computation/DepthProbeComputation.h" #include "Core/Computation/DepthProbeComputation.h"
#include "Core/Computation/IBackground.h" #include "Core/Computation/IBackground.h"
#include "Device/Beam/IFootprintFactor.h" #include "Device/Beam/IFootprintFactor.h"
#include "Device/Detector/SpecularDetector1D.h" #include "Device/Detector/SpecularDetector1D.h"
#include "Device/Instrument/CoordSystem2D.h" #include "Device/Instrument/CoordSystem2D.h"
#include "Param/Distrib/Distributions.h" #include "Param/Distrib/Distributions.h"
#include "Sample/SampleBuilderEngine/ISampleBuilder.h" #include "Sample/SampleBuilderEngine/ISampleBuilder.h"
namespace { namespace {
const RealLimits alpha_limits = RealLimits::limited(0.0, M_PI_2); const RealLimits alpha_limits = RealLimits::limited(0.0, M_PI_2);
const double zero_phi_i = 0.0; const double zero_phi_i = 0.0;
const double zero_alpha_i = 0.0; const double zero_alpha_i = 0.0;
} // namespace } // namespace
DepthProbeSimulation::DepthProbeSimulation() : ISimulation() DepthProbeSimulation::DepthProbeSimulation() : ISimulation()
{ {
initialize(); initialize();
} }
DepthProbeSimulation::~DepthProbeSimulation() = default; DepthProbeSimulation::~DepthProbeSimulation() = default;
DepthProbeSimulation* DepthProbeSimulation::clone() const DepthProbeSimulation* DepthProbeSimulation::clone() const
{ {
return new DepthProbeSimulation(*this); return new DepthProbeSimulation(*this);
} }
size_t DepthProbeSimulation::numberOfSimulationElements() const size_t DepthProbeSimulation::numberOfSimulationElements() const
{ {
return getAlphaAxis()->size(); return getAlphaAxis()->size();
} }
SimulationResult DepthProbeSimulation::result() const SimulationResult DepthProbeSimulation::result() const
{ {
validityCheck(); validityCheck();
auto data = createIntensityData(); auto data = createIntensityData();
return SimulationResult(*data, createCoordSystem()); return SimulationResult(*data, createCoordSystem());
} }
void DepthProbeSimulation::setBeamParameters(double lambda, int nbins, double alpha_i_min, void DepthProbeSimulation::setBeamParameters(double lambda, int nbins, double alpha_i_min,
double alpha_i_max, const IFootprintFactor* beam_shape) double alpha_i_max, const IFootprintFactor* beam_shape)
{ {
FixedBinAxis axis("alpha_i", static_cast<size_t>(nbins), alpha_i_min, alpha_i_max); FixedBinAxis axis("alpha_i", static_cast<size_t>(nbins), alpha_i_min, alpha_i_max);
setBeamParameters(lambda, axis, beam_shape); setBeamParameters(lambda, axis, beam_shape);
} }
void DepthProbeSimulation::setZSpan(size_t n_bins, double z_min, double z_max) void DepthProbeSimulation::setZSpan(size_t n_bins, double z_min, double z_max)
{ {
if (z_max <= z_min) if (z_max <= z_min)
throw std::runtime_error("Error in DepthProbeSimulation::setZSpan: maximum on-axis value " throw std::runtime_error("Error in DepthProbeSimulation::setZSpan: maximum on-axis value "
"is less or equal to the minimum one"); "is less or equal to the minimum one");
m_z_axis = std::make_unique<FixedBinAxis>("z", n_bins, z_min, z_max); m_z_axis = std::make_unique<FixedBinAxis>("z", n_bins, z_min, z_max);
} }
const IAxis* DepthProbeSimulation::getAlphaAxis() const const IAxis* DepthProbeSimulation::getAlphaAxis() const
{ {
if (!m_alpha_axis) if (!m_alpha_axis)
throw std::runtime_error("Error in DepthProbeSimulation::getAlphaAxis: incident angle axis " throw std::runtime_error("Error in DepthProbeSimulation::getAlphaAxis: incident angle axis "
"was not initialized."); "was not initialized.");
return m_alpha_axis.get(); return m_alpha_axis.get();
} }
const IAxis* DepthProbeSimulation::getZAxis() const const IAxis* DepthProbeSimulation::getZAxis() const
{ {
if (!m_z_axis) if (!m_z_axis)
throw std::runtime_error("Error in DepthProbeSimulation::getZAxis: position axis " throw std::runtime_error("Error in DepthProbeSimulation::getZAxis: position axis "
"was not initialized."); "was not initialized.");
return m_z_axis.get(); return m_z_axis.get();
} }
size_t DepthProbeSimulation::intensityMapSize() const size_t DepthProbeSimulation::intensityMapSize() const
{ {
if (!m_z_axis || !m_alpha_axis) if (!m_z_axis || !m_alpha_axis)
throw std::runtime_error("Error in DepthProbeSimulation::intensityMapSize: attempt to " throw std::runtime_error("Error in DepthProbeSimulation::intensityMapSize: attempt to "
"access non-initialized data."); "access non-initialized data.");
return m_z_axis->size() * m_alpha_axis->size(); return m_z_axis->size() * m_alpha_axis->size();
} }
#ifndef SWIG #ifndef SWIG
ICoordSystem* DepthProbeSimulation::createCoordSystem() const ICoordSystem* DepthProbeSimulation::createCoordSystem() const
{ {
return new DepthProbeCoordinates(beam(), *m_alpha_axis, *m_z_axis); return new DepthProbeCoordinates(beam(), *m_alpha_axis, *m_z_axis);
} }
#endif #endif
DepthProbeSimulation::DepthProbeSimulation(const DepthProbeSimulation& other) DepthProbeSimulation::DepthProbeSimulation(const DepthProbeSimulation& other)
: ISimulation(other), m_sim_elements(other.m_sim_elements), m_cache(other.m_cache) : ISimulation(other), m_sim_elements(other.m_sim_elements), m_cache(other.m_cache)
{ {
if (other.m_alpha_axis) if (other.m_alpha_axis)
m_alpha_axis.reset(other.m_alpha_axis->clone()); m_alpha_axis.reset(other.m_alpha_axis->clone());
if (other.m_z_axis) if (other.m_z_axis)
m_z_axis.reset(other.m_z_axis->clone()); m_z_axis.reset(other.m_z_axis->clone());
for (auto iter = m_sim_elements.begin(); iter != m_sim_elements.end(); ++iter) for (auto iter = m_sim_elements.begin(); iter != m_sim_elements.end(); ++iter)
iter->setZPositions(m_alpha_axis.get()); iter->setZPositions(m_alpha_axis.get());
initialize(); initialize();
} }
void DepthProbeSimulation::setBeamParameters(double lambda, const IAxis& alpha_axis, void DepthProbeSimulation::setBeamParameters(double lambda, const IAxis& alpha_axis,
const IFootprintFactor* beam_shape) const IFootprintFactor* beam_shape)
{ {
if (lambda <= 0.0) if (lambda <= 0.0)
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::setBeamParameters: wavelength must be positive."); "Error in DepthProbeSimulation::setBeamParameters: wavelength must be positive.");
if (alpha_axis.lowerBound() < 0.0) if (alpha_axis.lowerBound() < 0.0)
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::setBeamParameters: minimum value on " "Error in DepthProbeSimulation::setBeamParameters: minimum value on "
"angle axis is negative."); "angle axis is negative.");
if (alpha_axis.lowerBound() >= alpha_axis.upperBound()) if (alpha_axis.lowerBound() >= alpha_axis.upperBound())
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::setBeamParameters: maximal value on " "Error in DepthProbeSimulation::setBeamParameters: maximal value on "
"angle axis is less or equal to the minimal one."); "angle axis is less or equal to the minimal one.");
if (alpha_axis.size() == 0) if (alpha_axis.size() == 0)
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::setBeamParameters: angle axis is empty"); "Error in DepthProbeSimulation::setBeamParameters: angle axis is empty");
SpecularDetector1D detector(alpha_axis); SpecularDetector1D detector(alpha_axis);
instrument().setDetector(detector); instrument().setDetector(detector);
m_alpha_axis.reset(alpha_axis.clone()); m_alpha_axis.reset(alpha_axis.clone());
// beam is initialized with zero-valued angles // beam is initialized with zero-valued angles
// Zero-valued incident alpha is required for proper // Zero-valued incident alpha is required for proper
// taking into account beam resolution effects // taking into account beam resolution effects
instrument().setBeamParameters(lambda, zero_alpha_i, zero_phi_i); instrument().setBeamParameters(lambda, zero_alpha_i, zero_phi_i);
if (beam_shape) if (beam_shape)
beam().setFootprintFactor(*beam_shape); beam().setFootprintFactor(*beam_shape);
} }
void DepthProbeSimulation::initSimulationElementVector() void DepthProbeSimulation::initSimulationElementVector()
{ {
m_sim_elements = generateSimulationElements(beam()); m_sim_elements = generateSimulationElements(beam());
if (!m_cache.empty()) if (!m_cache.empty())
return; return;
m_cache.resize(m_sim_elements.size(), std::valarray<double>(0.0, getZAxis()->size())); m_cache.resize(m_sim_elements.size(), std::valarray<double>(0.0, getZAxis()->size()));
} }
std::vector<DepthProbeElement> DepthProbeSimulation::generateSimulationElements(const Beam& beam) std::vector<DepthProbeElement> DepthProbeSimulation::generateSimulationElements(const Beam& beam)
{ {
std::vector<DepthProbeElement> result; std::vector<DepthProbeElement> result;
const double wavelength = beam.wavelength(); const double wavelength = beam.wavelength();
const double angle_shift = beam.direction().alpha(); const double angle_shift = beam.direction().alpha();
const size_t axis_size = getAlphaAxis()->size(); const size_t axis_size = getAlphaAxis()->size();
result.reserve(axis_size); result.reserve(axis_size);
for (size_t i = 0; i < axis_size; ++i) { for (size_t i = 0; i < axis_size; ++i) {
double result_angle = incidentAngle(i) + angle_shift; double result_angle = incidentAngle(i) + angle_shift;
result.emplace_back(wavelength, -result_angle, getZAxis()); result.emplace_back(wavelength, -result_angle, getZAxis());
if (!alpha_limits.isInRange(result_angle)) if (!alpha_limits.isInRange(result_angle))
result.back().setCalculationFlag(false); // false = exclude from calculations result.back().setCalculationFlag(false); // false = exclude from calculations
} }
return result; return result;
} }
std::unique_ptr<IComputation> std::unique_ptr<IComputation>
DepthProbeSimulation::generateSingleThreadedComputation(size_t start, size_t n_elements) DepthProbeSimulation::generateSingleThreadedComputation(size_t start, size_t n_elements)
{ {
ASSERT(start < m_sim_elements.size() && start + n_elements <= m_sim_elements.size()); ASSERT(start < m_sim_elements.size() && start + n_elements <= m_sim_elements.size());
const auto& begin = m_sim_elements.begin() + static_cast<long>(start); const auto& begin = m_sim_elements.begin() + static_cast<long>(start);
return std::make_unique<DepthProbeComputation>(*sample(), options(), progress(), begin, return std::make_unique<DepthProbeComputation>(*sample(), options(), progress(), begin,
begin + static_cast<long>(n_elements)); begin + static_cast<long>(n_elements));
} }
void DepthProbeSimulation::validityCheck() const void DepthProbeSimulation::validityCheck() const
{ {
const MultiLayer* current_sample = sample(); const MultiLayer* current_sample = sample();
if (!current_sample) if (!current_sample)
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::validityCheck: no sample found in the simulation."); "Error in DepthProbeSimulation::validityCheck: no sample found in the simulation.");
const size_t data_size = m_sim_elements.size(); const size_t data_size = m_sim_elements.size();
if (data_size != getAlphaAxis()->size()) if (data_size != getAlphaAxis()->size())
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::validityCheck: length of simulation " "Error in DepthProbeSimulation::validityCheck: length of simulation "
"element vector is not equal to the number of inclination angles"); "element vector is not equal to the number of inclination angles");
} }
void DepthProbeSimulation::checkCache() const void DepthProbeSimulation::checkCache() const
{ {
if (m_sim_elements.size() != m_cache.size()) if (m_sim_elements.size() != m_cache.size())
throw std::runtime_error("Error in DepthProbeSimulation: the sizes of simulation element " throw std::runtime_error("Error in DepthProbeSimulation: the sizes of simulation element "
"vector and of its cache are different"); "vector and of its cache are different");
} }
void DepthProbeSimulation::validateParametrization(const ParameterDistribution& par_distr) const void DepthProbeSimulation::validateParametrization(const ParameterDistribution& par_distr) const
{ {
const bool zero_mean = par_distr.getDistribution()->getMean() == 0.0; const bool zero_mean = par_distr.getDistribution()->getMean() == 0.0;
if (zero_mean) if (zero_mean)
return; return;
if (par_distr.whichParameter() == ParameterDistribution::BeamInclinationAngle) if (par_distr.whichParameter() == ParameterDistribution::BeamInclinationAngle)
throw std::runtime_error("Error in DepthProbeSimulation: parameter distribution of " throw std::runtime_error("Error in DepthProbeSimulation: parameter distribution of "
"beam inclination angle should have zero mean."); "beam inclination angle should have zero mean.");
} }
void DepthProbeSimulation::initialize() void DepthProbeSimulation::initialize()
{ {
setName("DepthProbeSimulation"); setName("DepthProbeSimulation");
// allow for negative inclinations in the beam of specular simulation // allow for negative inclinations in the beam of specular simulation
// it is required for proper averaging in the case of divergent beam // it is required for proper averaging in the case of divergent beam
beam().setInclinationLimits(RealLimits::limited(-M_PI_2, M_PI_2)); beam().setInclinationLimits(RealLimits::limited(-M_PI_2, M_PI_2));
} }
void DepthProbeSimulation::normalize(size_t start_ind, size_t n_elements) void DepthProbeSimulation::normalize(size_t start_ind, size_t n_elements)
{ {
const double beam_intensity = beam().intensity(); const double beam_intensity = beam().intensity();
for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) { for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
auto& element = m_sim_elements[i]; auto& element = m_sim_elements[i];
const double alpha_i = -element.getAlphaI(); const double alpha_i = -element.getAlphaI();
const auto footprint = beam().footprintFactor(); const auto footprint = beam().footprintFactor();
double intensity_factor = beam_intensity; double intensity_factor = beam_intensity;
if (footprint != nullptr) if (footprint != nullptr)
intensity_factor = intensity_factor * footprint->calculate(alpha_i); intensity_factor = intensity_factor * footprint->calculate(alpha_i);
element.setIntensities(element.getIntensities() * intensity_factor); element.setIntensities(element.getIntensities() * intensity_factor);
} }
} }
void DepthProbeSimulation::addBackgroundIntensity(size_t, size_t) void DepthProbeSimulation::addBackgroundIntensity(size_t, size_t)
{ {
if (background()) if (background())
throw std::runtime_error( throw std::runtime_error(
"Error: nonzero background is not supported by DepthProbeSimulation"); "Error: nonzero background is not supported by DepthProbeSimulation");
} }
void DepthProbeSimulation::addDataToCache(double weight) void DepthProbeSimulation::addDataToCache(double weight)
{ {
checkCache(); checkCache();
for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i) for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
m_cache[i] += m_sim_elements[i].getIntensities() * weight; m_cache[i] += m_sim_elements[i].getIntensities() * weight;
} }
void DepthProbeSimulation::moveDataFromCache() void DepthProbeSimulation::moveDataFromCache()
{ {
checkCache(); checkCache();
for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i) for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
m_sim_elements[i].setIntensities(std::move(m_cache[i])); m_sim_elements[i].setIntensities(std::move(m_cache[i]));
m_cache.clear(); m_cache.clear();
m_cache.shrink_to_fit(); m_cache.shrink_to_fit();
} }
double DepthProbeSimulation::incidentAngle(size_t index) const double DepthProbeSimulation::incidentAngle(size_t index) const
{ {
return m_alpha_axis->bin(index).center(); return m_alpha_axis->bin(index).center();
} }
std::unique_ptr<OutputData<double>> DepthProbeSimulation::createIntensityData() const std::unique_ptr<OutputData<double>> DepthProbeSimulation::createIntensityData() const
{ {
std::unique_ptr<OutputData<double>> result = std::make_unique<OutputData<double>>(); std::unique_ptr<OutputData<double>> result = std::make_unique<OutputData<double>>();
result->addAxis(*getAlphaAxis()); result->addAxis(*getAlphaAxis());
result->addAxis(*getZAxis()); result->addAxis(*getZAxis());
std::vector<double> rawData; std::vector<double> rawData;
rawData.reserve(getAlphaAxis()->size() * getZAxis()->size()); rawData.reserve(getAlphaAxis()->size() * getZAxis()->size());
for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i) { for (size_t i = 0, size = m_sim_elements.size(); i < size; ++i) {
const std::valarray<double>& fixed_angle_result = m_sim_elements[i].getIntensities(); const std::valarray<double>& fixed_angle_result = m_sim_elements[i].getIntensities();
rawData.insert(rawData.end(), std::begin(fixed_angle_result), std::end(fixed_angle_result)); rawData.insert(rawData.end(), std::begin(fixed_angle_result), std::end(fixed_angle_result));
} }
result->setRawDataVector(rawData); result->setRawDataVector(rawData);
return result; return result;
} }
std::vector<double> DepthProbeSimulation::rawResults() const std::vector<double> DepthProbeSimulation::rawResults() const
{ {
validityCheck(); validityCheck();
const size_t z_size = getZAxis()->size(); const size_t z_size = getZAxis()->size();
const size_t alpha_size = getAlphaAxis()->size(); const size_t alpha_size = getAlphaAxis()->size();
std::vector<double> result; std::vector<double> result;
result.reserve(alpha_size * z_size); result.reserve(alpha_size * z_size);
for (size_t i = 0; i < alpha_size; ++i) { for (size_t i = 0; i < alpha_size; ++i) {
if (m_sim_elements[i].size() != z_size) if (m_sim_elements[i].size() != z_size)
throw std::runtime_error("Error in DepthProbeSimulation::rawResults: simulation " throw std::runtime_error("Error in DepthProbeSimulation::rawResults: simulation "
"element size is not equal to the size of the position axis"); "element size is not equal to the size of the position axis");
const auto& intensities = m_sim_elements[i].getIntensities(); const auto& intensities = m_sim_elements[i].getIntensities();
result.insert(result.end(), std::begin(intensities), std::end(intensities)); result.insert(result.end(), std::begin(intensities), std::end(intensities));
} }
return result; return result;
} }
void DepthProbeSimulation::setRawResults(const std::vector<double>& raw_results) void DepthProbeSimulation::setRawResults(const std::vector<double>& raw_results)
{ {
validityCheck(); validityCheck();
const size_t z_size = getZAxis()->size(); const size_t z_size = getZAxis()->size();
const size_t alpha_size = getAlphaAxis()->size(); const size_t alpha_size = getAlphaAxis()->size();
if (raw_results.size() != z_size * alpha_size) if (raw_results.size() != z_size * alpha_size)
throw std::runtime_error( throw std::runtime_error(
"Error in DepthProbeSimulation::setRawResults: the vector to set is of invalid size"); "Error in DepthProbeSimulation::setRawResults: the vector to set is of invalid size");
const double* raw_array = raw_results.data(); const double* raw_array = raw_results.data();
for (size_t i = 0; i < alpha_size; ++i) { for (size_t i = 0; i < alpha_size; ++i) {
std::valarray<double> fixed_angle_result(raw_array, z_size); std::valarray<double> fixed_angle_result(raw_array, z_size);
m_sim_elements[i].setIntensities(std::move(fixed_angle_result)); m_sim_elements[i].setIntensities(std::move(fixed_angle_result));
raw_array += z_size; raw_array += z_size;
} }
} }
// ************************************************************************************************ // ************************************************************************************************
// //
// BornAgain: simulate and fit reflection and scattering // BornAgain: simulate and fit reflection and scattering
// //
//! @file Core/Simulation/OffSpecularSimulation.cpp //! @file Core/Simulation/OffSpecularSimulation.cpp
//! @brief Implements class OffSpecularSimulation. //! @brief Implements class OffSpecularSimulation.
//! //!
//! @homepage http://www.bornagainproject.org //! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING) //! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018 //! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
// //
// ************************************************************************************************ // ************************************************************************************************
#include "Core/Simulation/OffSpecularSimulation.h" #include "Core/Simulation/OffSpecularSimulation.h"
#include "Device/Instrument/CoordSystem2D.h" #include "Device/Instrument/CoordSystem2D.h"
#include "Param/Distrib/Distributions.h" #include "Param/Distrib/Distributions.h"
#include "Sample/SampleBuilderEngine/ISampleBuilder.h" #include "Sample/SampleBuilderEngine/ISampleBuilder.h"
OffSpecularSimulation::OffSpecularSimulation(const Beam& beam, const MultiLayer& sample, OffSpecularSimulation::OffSpecularSimulation(const Beam& beam, const MultiLayer& sample,
const IDetector& detector) const IDetector& detector)
: ISimulation2D(beam, sample, detector) : ISimulation2D(beam, sample, detector)
{ {
} }
OffSpecularSimulation::OffSpecularSimulation() OffSpecularSimulation::OffSpecularSimulation()
{ {
initialize(); initialize();
} }
void OffSpecularSimulation::prepareSimulation() void OffSpecularSimulation::prepareSimulation()
{ {
checkInitialization(); checkInitialization();
ISimulation2D::prepareSimulation(); ISimulation2D::prepareSimulation();
} }
size_t OffSpecularSimulation::numberOfSimulationElements() const size_t OffSpecularSimulation::numberOfSimulationElements() const
{ {
checkInitialization(); checkInitialization();
return ISimulation2D::numberOfSimulationElements() * m_alpha_i_axis->size(); return ISimulation2D::numberOfSimulationElements() * m_alpha_i_axis->size();
} }
SimulationResult OffSpecularSimulation::result() const SimulationResult OffSpecularSimulation::result() const
{ {
auto data = std::unique_ptr<OutputData<double>>(m_intensity_map.clone()); auto data = std::unique_ptr<OutputData<double>>(m_intensity_map.clone());
OffSpecularCoordinates converter(detector2D(), beam(), *m_alpha_i_axis); OffSpecularCoordinates converter(detector2D(), beam(), *m_alpha_i_axis);
return SimulationResult(*data, converter); return SimulationResult(*data, converter);
} }
void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis& alpha_axis, void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis& alpha_axis,
double phi_i) double phi_i)
{ {
m_alpha_i_axis.reset(alpha_axis.clone()); m_alpha_i_axis.reset(alpha_axis.clone());
if (alpha_axis.size() < 1) if (alpha_axis.size() < 1)
throw std::runtime_error("OffSpecularSimulation::prepareSimulation() " throw std::runtime_error("OffSpecularSimulation::prepareSimulation() "
"-> Error. Incoming alpha range size < 1."); "-> Error. Incoming alpha range size < 1.");
const double alpha_zero = alpha_axis.lowerBound(); const double alpha_zero = alpha_axis.lowerBound();
instrument().setBeamParameters(wavelength, alpha_zero, phi_i); instrument().setBeamParameters(wavelength, alpha_zero, phi_i);
updateIntensityMap(); updateIntensityMap();
} }
const IAxis* OffSpecularSimulation::beamAxis() const const IAxis* OffSpecularSimulation::beamAxis() const
{ {
return m_alpha_i_axis.get(); return m_alpha_i_axis.get();
} }
#ifndef SWIG #ifndef SWIG
ICoordSystem* OffSpecularSimulation::createCoordSystem() const ICoordSystem* OffSpecularSimulation::createCoordSystem() const
{ {
const IAxis* axis = beamAxis(); const IAxis* axis = beamAxis();
if (!axis) if (!axis)
throw std::runtime_error("Error in OffSpecularSimulation::createCoordSystem:" throw std::runtime_error("Error in OffSpecularSimulation::createCoordSystem:"
" missing inclination angle axis"); " missing inclination angle axis");
return new OffSpecularCoordinates(detector2D(), beam(), *axis); return new OffSpecularCoordinates(detector2D(), beam(), *axis);
} }
#endif #endif
size_t OffSpecularSimulation::intensityMapSize() const size_t OffSpecularSimulation::intensityMapSize() const
{ {
checkInitialization(); checkInitialization();
return m_alpha_i_axis->size() * detector().axis(1).size(); return m_alpha_i_axis->size() * detector().axis(1).size();
} }
OffSpecularSimulation::OffSpecularSimulation(const OffSpecularSimulation& other) OffSpecularSimulation::OffSpecularSimulation(const OffSpecularSimulation& other)
: ISimulation2D(other) : ISimulation2D(other)
{ {
if (other.m_alpha_i_axis) if (other.m_alpha_i_axis)
m_alpha_i_axis.reset(other.m_alpha_i_axis->clone()); m_alpha_i_axis.reset(other.m_alpha_i_axis->clone());
m_intensity_map.copyFrom(other.m_intensity_map); m_intensity_map.copyFrom(other.m_intensity_map);
initialize(); initialize();
} }
void OffSpecularSimulation::initSimulationElementVector() void OffSpecularSimulation::initSimulationElementVector()
{ {
m_sim_elements.clear(); m_sim_elements.clear();
Beam beam2 = beam(); Beam beam2 = beam();
for (size_t i = 0; i < m_alpha_i_axis->size(); ++i) { for (size_t i = 0; i < m_alpha_i_axis->size(); ++i) {
beam2.setInclination(m_alpha_i_axis->bin(i).center()); beam2.setInclination(m_alpha_i_axis->bin(i).center());
std::vector<SimulationElement> sim_elements_i = generateSimulationElements(beam2); std::vector<SimulationElement> sim_elements_i = generateSimulationElements(beam2);
for (auto ele : sim_elements_i) for (auto ele : sim_elements_i)
m_sim_elements.emplace_back(ele); m_sim_elements.emplace_back(ele);
} }
if (m_cache.empty()) if (m_cache.empty())
m_cache.resize(m_sim_elements.size(), 0.0); m_cache.resize(m_sim_elements.size(), 0.0);
} }
void OffSpecularSimulation::validateParametrization(const ParameterDistribution& par_distr) const void OffSpecularSimulation::validateParametrization(const ParameterDistribution& par_distr) const
{ {
const bool zero_mean = par_distr.getDistribution()->getMean() == 0.0; const bool zero_mean = par_distr.getDistribution()->getMean() == 0.0;
if (zero_mean) if (zero_mean)
return; return;
if (par_distr.whichParameter() == ParameterDistribution::BeamInclinationAngle) if (par_distr.whichParameter() == ParameterDistribution::BeamInclinationAngle)
throw std::runtime_error("Error in OffSpecularSimulation: parameter distribution of " throw std::runtime_error("Error in OffSpecularSimulation: parameter distribution of "
"beam inclination angle should have zero mean."); "beam inclination angle should have zero mean.");
} }
void OffSpecularSimulation::transferResultsToIntensityMap() void OffSpecularSimulation::transferResultsToIntensityMap()
{ {
checkInitialization(); checkInitialization();
const IAxis& phi_axis = detector().axis(0); const IAxis& phi_axis = detector().axis(0);
size_t phi_f_size = phi_axis.size(); size_t phi_f_size = phi_axis.size();
if (phi_f_size * m_intensity_map.getAllocatedSize() != m_sim_elements.size()) if (phi_f_size * m_intensity_map.getAllocatedSize() != m_sim_elements.size())
throw std::runtime_error( throw std::runtime_error(
"OffSpecularSimulation::transferResultsToIntensityMap: " "OffSpecularSimulation::transferResultsToIntensityMap: "
"intensity map size does not conform to number of calculated intensities"); "intensity map size does not conform to number of calculated intensities");
for (size_t i = 0; i < m_alpha_i_axis->size(); ++i) for (size_t i = 0; i < m_alpha_i_axis->size(); ++i)
transferDetectorImage(i); transferDetectorImage(i);
} }
void OffSpecularSimulation::updateIntensityMap() void OffSpecularSimulation::updateIntensityMap()
{ {
m_intensity_map.clear(); m_intensity_map.clear();
if (m_alpha_i_axis) if (m_alpha_i_axis)
m_intensity_map.addAxis(*m_alpha_i_axis); m_intensity_map.addAxis(*m_alpha_i_axis);
size_t detector_dimension = detector().dimension(); size_t detector_dimension = detector().dimension();
if (detector_dimension == 2) if (detector_dimension == 2)
m_intensity_map.addAxis(detector().axis(1)); m_intensity_map.addAxis(detector().axis(1));
m_intensity_map.setAllTo(0.); m_intensity_map.setAllTo(0.);
} }
void OffSpecularSimulation::transferDetectorImage(size_t index) void OffSpecularSimulation::transferDetectorImage(size_t index)
{ {
OutputData<double> detector_image; OutputData<double> detector_image;
size_t detector_dimension = detector().dimension(); size_t detector_dimension = detector().dimension();
for (size_t dim = 0; dim < detector_dimension; ++dim) for (size_t dim = 0; dim < detector_dimension; ++dim)
detector_image.addAxis(detector().axis(dim)); detector_image.addAxis(detector().axis(dim));
size_t detector_size = detector_image.getAllocatedSize(); size_t detector_size = detector_image.getAllocatedSize();
for (size_t i = 0; i < detector_size; ++i) for (size_t i = 0; i < detector_size; ++i)
detector_image[i] = m_sim_elements[index * detector_size + i].intensity(); detector_image[i] = m_sim_elements[index * detector_size + i].intensity();
detector().applyDetectorResolution(&detector_image); detector().applyDetectorResolution(&detector_image);
size_t y_axis_size = detector().axis(1).size(); size_t y_axis_size = detector().axis(1).size();
for (size_t i = 0; i < detector_size; ++i) for (size_t i = 0; i < detector_size; ++i)
m_intensity_map[index * y_axis_size + i % y_axis_size] += detector_image[i]; m_intensity_map[index * y_axis_size + i % y_axis_size] += detector_image[i];
} }
void OffSpecularSimulation::checkInitialization() const void OffSpecularSimulation::checkInitialization() const
{ {
if (!m_alpha_i_axis || m_alpha_i_axis->size() < 1) if (!m_alpha_i_axis || m_alpha_i_axis->size() < 1)
throw std::runtime_error("OffSpecularSimulation::checkInitialization() " throw std::runtime_error("OffSpecularSimulation::checkInitialization() "
"Incoming alpha range not configured."); "Incoming alpha range not configured.");
if (detector().dimension() != 2) if (detector().dimension() != 2)
throw std::runtime_error( throw std::runtime_error(
"OffSpecularSimulation::checkInitialization: detector is not two-dimensional"); "OffSpecularSimulation::checkInitialization: detector is not two-dimensional");
} }
void OffSpecularSimulation::initialize() void OffSpecularSimulation::initialize()
{ {
setName("OffSpecularSimulation"); setName("OffSpecularSimulation");
} }
// ************************************************************************************************ // ************************************************************************************************
// //
// BornAgain: simulate and fit reflection and scattering // BornAgain: simulate and fit reflection and scattering
// //
//! @file GUI/coregui/Models/GUIExamplesFactory.cpp //! @file GUI/coregui/Models/GUIExamplesFactory.cpp
//! @brief Implements class GUIExamplesFactory //! @brief Implements class GUIExamplesFactory
//! //!
//! @homepage http://www.bornagainproject.org //! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING) //! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018 //! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
// //
// ************************************************************************************************ // ************************************************************************************************
#include "GUI/coregui/Models/GUIExamplesFactory.h" #include "GUI/coregui/Models/GUIExamplesFactory.h"
#include "GUI/coregui/Models/GUIObjectBuilder.h" #include "GUI/coregui/Models/GUIObjectBuilder.h"
#include "Sample/Multilayer/MultiLayer.h" #include "Sample/Multilayer/MultiLayer.h"
#include "Sample/StandardSamples/SampleBuilderFactory.h" #include "Sample/StandardSamples/SampleBuilderFactory.h"
#include <memory> #include <memory>
//! Defines correspondence between example name and real name of simulation from SimulationFactory //! Defines correspondence between example name and real name of simulation from SimulationFactory
QMap<QString, QString> init_NameToRegistry() QMap<QString, QString> init_NameToRegistry()
{ {
QMap<QString, QString> result; QMap<QString, QString> result;
result["example01"] = "CylindersAndPrismsBuilder"; result["example01"] = "CylindersAndPrismsBuilder";
result["example02"] = "RadialParaCrystalBuilder"; result["example02"] = "RadialParaCrystalBuilder";
result["example03"] = "HexParaCrystalBuilder"; result["example03"] = "HexParaCrystalBuilder";
result["example04"] = "CoreShellParticleBuilder"; result["example04"] = "CoreShellParticleBuilder";
result["example05"] = "MultiLayerWithRoughnessBuilder"; result["example05"] = "MultiLayerWithRoughnessBuilder";
result["example06"] = "SquareLattice2DBuilder"; result["example06"] = "SquareLattice2DBuilder";
result["example07"] = "RotatedPyramidsBuilder"; result["example07"] = "RotatedPyramidsBuilder";
result["example09"] = "ParticleCompositionBuilder"; result["example09"] = "ParticleCompositionBuilder";
result["example10"] = "MesoCrystalBuilder"; result["example10"] = "MesoCrystalBuilder";
// temporary for testing // temporary for testing
// result["example09"] = "MultipleLayoutBuilder"; // result["example09"] = "MultipleLayoutBuilder";
// result["example09"] = "TwoTypesCylindersDistributionBuilder"; // result["example09"] = "TwoTypesCylindersDistributionBuilder";
// result["example09"] = "RectParaCrystalBuilder"; // result["example09"] = "RectParaCrystalBuilder";
// result["example09"] = "SizeDistributionLMAModelBuilder"; // result["example09"] = "SizeDistributionLMAModelBuilder";
// result["example09"] = "CylindersInSSCABuilder"; // result["example09"] = "CylindersInSSCABuilder";
// result["example09"] = "TransformBoxBuilder"; // result["example09"] = "TransformBoxBuilder";
// result["example09"] = "BoxCompositionRotateZandYBuilder"; // result["example09"] = "BoxCompositionRotateZandYBuilder";
// result["example09"] = "CoreShellBoxRotateZandYBuilder"; // result["example09"] = "CoreShellBoxRotateZandYBuilder";
// result["example09"] = "BoxStackCompositionBuilder"; // result["example09"] = "BoxStackCompositionBuilder";
// result["example09"] = "LargeCylindersInDWBABuilder"; // result["example09"] = "LargeCylindersInDWBABuilder";
// result["example09"] = "SlicedCompositionBuilder"; // result["example09"] = "SlicedCompositionBuilder";
// result["example09"] = "RotatedPyramidsDistributionBuilder"; // result["example09"] = "RotatedPyramidsDistributionBuilder";
// result["example09"] = "SpheresWithLimitsDistributionBuilder"; // result["example09"] = "SpheresWithLimitsDistributionBuilder";
// result["example09"] = "ConesWithLimitsDistributionBuilder"; // result["example09"] = "ConesWithLimitsDistributionBuilder";
return result; return result;
} }
QMap<QString, QString> GUIExamplesFactory::m_name_to_registry = init_NameToRegistry(); QMap<QString, QString> GUIExamplesFactory::m_name_to_registry = init_NameToRegistry();
bool GUIExamplesFactory::isValidExampleName(const QString& name) bool GUIExamplesFactory::isValidExampleName(const QString& name)
{ {
return m_name_to_registry.contains(name); return m_name_to_registry.contains(name);
} }
//! Populate sample model with //! Populate sample model with
SessionItem* GUIExamplesFactory::createSampleItems(const QString& name, SampleModel* sampleModel, SessionItem* GUIExamplesFactory::createSampleItems(const QString& name, SampleModel* sampleModel,
MaterialModel* materialModel) MaterialModel* materialModel)
{ {
QString exampleName = m_name_to_registry[name]; QString exampleName = m_name_to_registry[name];
SampleBuilderFactory factory; SampleBuilderFactory factory;
const std::unique_ptr<MultiLayer> sample(factory.createSampleByName(exampleName.toStdString())); const std::unique_ptr<MultiLayer> sample(factory.createSampleByName(exampleName.toStdString()));
return GUIObjectBuilder::populateSampleModel(sampleModel, materialModel, *sample.get(), name); return GUIObjectBuilder::populateSampleModel(sampleModel, materialModel, *sample.get(), name);
} }
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