33 const double zero_phi_i = 0.0;
 
   34 const double zero_alpha_i = 0.0;
 
   37 DepthProbeSimulation::DepthProbeSimulation() : 
Simulation()
 
   42 DepthProbeSimulation::~DepthProbeSimulation() = 
default;
 
   49 size_t DepthProbeSimulation::numberOfSimulationElements()
 const 
   57     auto data = createIntensityData();
 
   64     FixedBinAxis axis(
"alpha_i", 
static_cast<size_t>(nbins), alpha_i_min, alpha_i_max);
 
   71         throw std::runtime_error(
"Error in DepthProbeSimulation::setZSpan: maximum on-axis value " 
   72                                  "is less or equal to the minimum one");
 
   73     m_z_axis = std::make_unique<FixedBinAxis>(
"z", n_bins, z_min, z_max);
 
   79         throw std::runtime_error(
"Error in DepthProbeSimulation::getAlphaAxis: incident angle axis " 
   80                                  "was not initialized.");
 
   81     return m_alpha_axis.get();
 
   87         throw std::runtime_error(
"Error in DepthProbeSimulation::getZAxis: position axis " 
   88                                  "was not initialized.");
 
   89     return m_z_axis.get();
 
   94     if (!m_z_axis || !m_alpha_axis)
 
   95         throw std::runtime_error(
"Error in DepthProbeSimulation::intensityMapSize: attempt to " 
   96                                  "access non-initialized data.");
 
   97     return m_z_axis->size() * m_alpha_axis->size();
 
  100 std::unique_ptr<IUnitConverter> DepthProbeSimulation::createUnitConverter()
 const 
  102     return std::make_unique<DepthProbeConverter>(instrument().getBeam(), *m_alpha_axis, *m_z_axis);
 
  106     : 
Simulation(other), m_sim_elements(other.m_sim_elements), m_cache(other.m_cache)
 
  108     if (other.m_alpha_axis)
 
  109         m_alpha_axis.reset(other.m_alpha_axis->clone());
 
  111         m_z_axis.reset(other.m_z_axis->clone());
 
  112     for (
auto iter = m_sim_elements.begin(); iter != m_sim_elements.end(); ++iter)
 
  113         iter->setZPositions(m_alpha_axis.get());
 
  121         throw std::runtime_error(
 
  122             "Error in DepthProbeSimulation::setBeamParameters: wavelength must be positive.");
 
  123     if (alpha_axis.
getMin() < 0.0)
 
  124         throw std::runtime_error(
 
  125             "Error in DepthProbeSimulation::setBeamParameters: minimum value on " 
  126             "angle axis is negative.");
 
  128         throw std::runtime_error(
 
  129             "Error in DepthProbeSimulation::setBeamParameters: maximal value on " 
  130             "angle axis is less or equal to the minimal one.");
 
  131     if (alpha_axis.
size() == 0)
 
  132         throw std::runtime_error(
 
  133             "Error in DepthProbeSimulation::setBeamParameters: angle axis is empty");
 
  137     m_alpha_axis.reset(alpha_axis.
clone());
 
  148 void DepthProbeSimulation::initSimulationElementVector()
 
  150     const auto& beam = instrument().getBeam();
 
  151     m_sim_elements = generateSimulationElements(beam);
 
  153     if (!m_cache.empty())
 
  155     m_cache.resize(m_sim_elements.size(), std::valarray<double>(0.0, 
getZAxis()->size()));
 
  158 std::vector<DepthProbeElement> DepthProbeSimulation::generateSimulationElements(
const Beam& beam)
 
  160     std::vector<DepthProbeElement> 
result;
 
  162     const double wavelength = beam.getWavelength();
 
  163     const double angle_shift = beam.getAlpha();
 
  166     result.reserve(axis_size);
 
  167     for (
size_t i = 0; i < axis_size; ++i) {
 
  168         double result_angle = incidentAngle(i) + angle_shift;
 
  170         if (!alpha_limits.isInRange(result_angle))
 
  171             result.back().setCalculationFlag(
false); 
 
  176 std::unique_ptr<IComputation>
 
  177 DepthProbeSimulation::generateSingleThreadedComputation(
size_t start, 
size_t n_elements)
 
  179     ASSERT(start < m_sim_elements.size() && start + n_elements <= m_sim_elements.size());
 
  180     const auto& begin = m_sim_elements.begin() + 
static_cast<long>(start);
 
  181     return std::make_unique<DepthProbeComputation>(*sample(), options(), progress(), begin,
 
  182                                                    begin + 
static_cast<long>(n_elements));
 
  185 void DepthProbeSimulation::validityCheck()
 const 
  189         throw std::runtime_error(
 
  190             "Error in DepthProbeSimulation::validityCheck: no sample found in the simulation.");
 
  192     const size_t data_size = m_sim_elements.size();
 
  194         throw std::runtime_error(
 
  195             "Error in DepthProbeSimulation::validityCheck: length of simulation " 
  196             "element vector is not equal to the number of inclination angles");
 
  199 void DepthProbeSimulation::checkCache()
 const 
  201     if (m_sim_elements.size() != m_cache.size())
 
  202         throw std::runtime_error(
"Error in DepthProbeSimulation: the sizes of simulation element " 
  203                                  "vector and of its cache are different");
 
  208     const bool zero_mean = par_distr.getDistribution()->
getMean() == 0.0;
 
  213     const std::vector<RealParameter*> names =
 
  215     for (
const auto par : names)
 
  216         if (par->getName().find(
"InclinationAngle") != std::string::npos && !zero_mean)
 
  217             throw std::runtime_error(
"Error in DepthProbeSimulation: parameter distribution of " 
  218                                      "beam inclination angle should have zero mean.");
 
  221 void DepthProbeSimulation::initialize()
 
  223     setName(
"DepthProbeSimulation");
 
  227     auto inclination = instrument().getBeam().
parameter(
"InclinationAngle");
 
  231 void DepthProbeSimulation::normalize(
size_t start_ind, 
size_t n_elements)
 
  233     const double beam_intensity = getBeamIntensity();
 
  234     if (beam_intensity == 0.0)
 
  236     for (
size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
 
  237         auto& element = m_sim_elements[i];
 
  238         const double alpha_i = -element.getAlphaI();
 
  240         double intensity_factor = beam_intensity;
 
  241         if (footprint != 
nullptr)
 
  242             intensity_factor = intensity_factor * footprint->
calculate(alpha_i);
 
  243         element.setIntensities(element.getIntensities() * intensity_factor);
 
  247 void DepthProbeSimulation::addBackgroundIntensity(
size_t, 
size_t)
 
  250         throw std::runtime_error(
 
  251             "Error: nonzero background is not supported by DepthProbeSimulation");
 
  254 void DepthProbeSimulation::addDataToCache(
double weight)
 
  257     for (
size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
 
  258         m_cache[i] += m_sim_elements[i].getIntensities() * weight;
 
  261 void DepthProbeSimulation::moveDataFromCache()
 
  264     for (
size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
 
  265         m_sim_elements[i].setIntensities(std::move(m_cache[i]));
 
  267     m_cache.shrink_to_fit();
 
  270 double DepthProbeSimulation::incidentAngle(
size_t index)
 const 
  272     return m_alpha_axis->getBin(index).getMidPoint();
 
  275 std::unique_ptr<OutputData<double>> DepthProbeSimulation::createIntensityData()
 const 
  277     std::unique_ptr<OutputData<double>> 
result = std::make_unique<OutputData<double>>();
 
  281     std::vector<double> rawData;
 
  283     for (
size_t i = 0, size = m_sim_elements.size(); i < size; ++i) {
 
  284         const std::valarray<double>& fixed_angle_result = m_sim_elements[i].getIntensities();
 
  285         rawData.insert(rawData.end(), std::begin(fixed_angle_result), std::end(fixed_angle_result));
 
  287     result->setRawDataVector(rawData);
 
  292 std::vector<double> DepthProbeSimulation::rawResults()
 const 
  298     std::vector<double> 
result;
 
  299     result.reserve(alpha_size * z_size);
 
  300     for (
size_t i = 0; i < alpha_size; ++i) {
 
  301         if (m_sim_elements[i].size() != z_size)
 
  302             throw std::runtime_error(
"Error in DepthProbeSimulation::rawResults: simulation " 
  303                                      "element size is not equal to the size of the position axis");
 
  304         const auto& intensities = m_sim_elements[i].getIntensities();
 
  305         result.insert(
result.end(), std::begin(intensities), std::end(intensities));
 
  311 void DepthProbeSimulation::setRawResults(
const std::vector<double>& raw_results)
 
  317     if (raw_results.size() != z_size * alpha_size)
 
  318         throw std::runtime_error(
 
  319             "Error in DepthProbeSimulation::setRawResults: the vector to set is of invalid size");
 
  321     const double* raw_array = raw_results.data();
 
  322     for (
size_t i = 0; i < alpha_size; ++i) {
 
  323         std::valarray<double> fixed_angle_result(raw_array, z_size);
 
  324         m_sim_elements[i].setIntensities(std::move(fixed_angle_result));
 
Declares class DepthProbeComputation.
 
Defines class DepthProbeSimulation.
 
Defines classes representing one-dimensional distributions.
 
Defines class Histogram1D.
 
Defines interface IBackground.
 
Defines pure virtual base class ISampleBuilder.
 
Declares functions in namespace MaterialUtils.
 
Defines M_PI and some more mathematical constants.
 
Defines class MultiLayer.
 
Defines class ParameterPool.
 
Defines class RealParameter.
 
Defines interface UnitConverterSimple and its subclasses.
 
Defines a detector for specular simulations.
 
Beam defined by wavelength, direction and intensity.
 
const IFootprintFactor * footprintFactor() const
Returns footprint factor.
 
void setFootprintFactor(const IFootprintFactor &shape_factor)
Sets footprint factor to the beam.
 
const IAxis * getAlphaAxis() const
Returns a pointer to incident angle axis.
 
SimulationResult result() const override
Returns the results of the simulation in a format that supports unit conversion and export to numpy a...
 
void setBeamParameters(double lambda, int nbins, double alpha_i_min, double alpha_i_max, const IFootprintFactor *beam_shape=nullptr)
Sets beam parameters with alpha_i of the beam defined in the range.
 
void setZSpan(size_t n_bins, double z_min, double z_max)
Set z positions for intensity calculations.
 
const IAxis * getZAxis() const
Returns a pointer to z-position axis.
 
size_t intensityMapSize() const override
Returns the total number of the intensity values in the simulation result.
 
Axis with fixed bin size.
 
Interface for one-dimensional axes.
 
virtual IAxis * clone() const =0
clone function
 
virtual double getMin() const =0
Returns value of first point of axis.
 
virtual size_t size() const =0
retrieve the number of bins
 
virtual double getMax() const =0
Returns value of last point of axis.
 
virtual double getMean() const =0
Returns the distribution-specific mean.
 
ParameterPool * createParameterTree() const
Creates new parameter pool, with all local parameters and those of its children.
 
RealParameter * parameter(const std::string &name) const
Returns parameter with given 'name'.
 
void setBeamParameters(double wavelength, double alpha_i, double phi_i)
Sets the beam wavelength and incoming angles.
 
void setDetector(const IDetector &detector)
Sets the detector (axes can be overwritten later)
 
Our sample model: a stack of layers one below the other.
 
A parametric distribution function, for use with any model parameter.
 
std::string getMainParameterName() const
get the main parameter's name
 
Limits for a real fit parameter.
 
static RealLimits limited(double left_bound_value, double right_bound_value)
Creates an object bounded from the left and right.
 
Wrapper around OutputData<double> that also provides unit conversions.
 
Pure virtual base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
 
1D detector for specular simulations.