25 OffSpecSimulation::OffSpecSimulation()
32 checkInitialization();
36 size_t OffSpecSimulation::numberOfSimulationElements()
const
38 checkInitialization();
44 auto data = std::unique_ptr<OutputData<double>>(m_intensity_map.clone());
52 mP_alpha_i_axis.reset(alpha_axis.
clone());
53 if (alpha_axis.
size() < 1)
55 "-> Error. Incoming alpha range size < 1.");
56 const double alpha_zero = alpha_axis.
getMin();
63 return mP_alpha_i_axis.get();
66 std::unique_ptr<IUnitConverter> OffSpecSimulation::createUnitConverter()
const
70 throw std::runtime_error(
"Error in OffSpecSimulation::createUnitConverter:"
71 " missing inclination angle axis");
72 return std::make_unique<OffSpecularConverter>(instrument().detector2D(), instrument().getBeam(),
78 checkInitialization();
79 return mP_alpha_i_axis->size() * instrument().getDetectorAxis(1).
size();
84 if (other.mP_alpha_i_axis)
85 mP_alpha_i_axis.reset(other.mP_alpha_i_axis->clone());
86 m_intensity_map.copyFrom(other.m_intensity_map);
90 void OffSpecSimulation::initSimulationElementVector()
92 m_sim_elements.clear();
93 Beam beam = instrument().getBeam();
94 const double wavelength = beam.getWavelength();
95 const double phi_i = beam.getPhi();
97 for (
size_t i = 0; i < mP_alpha_i_axis->size(); ++i) {
99 double alpha_i = mP_alpha_i_axis->getBin(i).getMidPoint();
100 double total_alpha = alpha_i;
103 m_sim_elements.insert(m_sim_elements.end(), std::make_move_iterator(sim_elements_i.begin()),
104 std::make_move_iterator(sim_elements_i.end()));
107 m_cache.resize(m_sim_elements.size(), 0.0);
112 const bool zero_mean = par_distr.getDistribution()->
getMean() == 0.0;
117 const std::vector<RealParameter*> names =
119 for (
const auto par : names)
120 if (par->getName().find(
"InclinationAngle") != std::string::npos && !zero_mean)
121 throw std::runtime_error(
"Error in OffSpecSimulation: parameter distribution of "
122 "beam inclination angle should have zero mean.");
125 void OffSpecSimulation::transferResultsToIntensityMap()
127 checkInitialization();
128 const IAxis& phi_axis = instrument().getDetectorAxis(0);
129 size_t phi_f_size = phi_axis.
size();
130 if (phi_f_size * m_intensity_map.
getAllocatedSize() != m_sim_elements.size())
132 "OffSpecSimulation::transferResultsToIntensityMap: "
133 "intensity map size does not conform to number of calculated intensities");
134 for (
size_t i = 0; i < mP_alpha_i_axis->size(); ++i)
135 transferDetectorImage(i);
138 void OffSpecSimulation::updateIntensityMap()
140 m_intensity_map.
clear();
142 m_intensity_map.addAxis(*mP_alpha_i_axis);
143 size_t detector_dimension = instrument().getDetectorDimension();
144 if (detector_dimension == 2)
145 m_intensity_map.addAxis(instrument().getDetectorAxis(1));
149 void OffSpecSimulation::transferDetectorImage(
size_t index)
152 size_t detector_dimension = instrument().getDetectorDimension();
153 for (
size_t dim = 0; dim < detector_dimension; ++dim)
154 detector_image.addAxis(instrument().getDetectorAxis(dim));
156 for (
size_t i = 0; i < detector_size; ++i)
157 detector_image[i] = m_sim_elements[index * detector_size + i].getIntensity();
159 size_t y_axis_size = instrument().getDetectorAxis(1).
size();
160 for (
size_t i = 0; i < detector_size; ++i)
161 m_intensity_map[index * y_axis_size + i % y_axis_size] += detector_image[i];
164 void OffSpecSimulation::checkInitialization()
const
166 if (!mP_alpha_i_axis || mP_alpha_i_axis->size() < 1)
168 "Incoming alpha range not configured.");
169 if (instrument().getDetectorDimension() != 2)
171 "OffSpecSimulation::checkInitialization: detector is not two-dimensional");
174 void OffSpecSimulation::initialize()
176 setName(
"OffSpecSimulation");
Defines class DWBAComputation.
Defines classes representing one-dimensional distributions.
Defines class Histogram2D.
Defines pure virtual base class ISampleBuilder.
Defines class MultiLayer.
Defines class OffSpecSimulation.
Defines class ParameterPool.
Defines class RealParameter.
Defines interface UnitConverterSimple and its subclasses.
Beam defined by wavelength, direction and intensity.
void setCentralK(double wavelength, double alpha_i, double phi_i)
Sets the wavevector in terms of wavelength and incoming angles.
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 getMean() const =0
Returns the distribution-specific mean.
ParameterPool * createParameterTree() const
Creates new parameter pool, with all local parameters and those of its children.
void applyDetectorResolution(OutputData< double > *p_intensity_map) const
apply the detector resolution to the given intensity map
void setBeamParameters(double wavelength, double alpha_i, double phi_i)
Sets the beam wavelength and incoming angles.
Main class to run an off-specular simulation.
SimulationResult result() const override
Returns the results of the simulation in a format that supports unit conversion and export to numpy a...
const IAxis * beamAxis() const
Returns axis of the beam.
size_t intensityMapSize() const override
Returns the total number of the intensity values in the simulation result.
void prepareSimulation() final
Put into a clean state for running a simulation.
void setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)
Sets beam parameters from here (forwarded to Instrument)
IUnitConverter class that handles the unit translations for off-specular simulations with a spherical...
void setAllTo(const T &value)
Sets content of output data to specific value.
size_t getAllocatedSize() const
Returns total size of data buffer (product of bin number in every dimension).
void clear()
Sets object into initial state (no dimensions, data)
A parametric distribution function, for use with any model parameter.
std::string getMainParameterName() const
get the main parameter's name
Pure virtual base class of OffSpecularSimulation and GISASSimulation.
size_t numberOfSimulationElements() const override
Gets the number of elements this simulation needs to calculate.
std::vector< SimulationElement > generateSimulationElements(const Beam &beam)
Generate simulation elements for given beam.
void prepareSimulation() override
Put into a clean state for running a simulation.
Wrapper around OutputData<double> that also provides unit conversions.