35 const double wl = beam.getWavelength();
36 const double angle_shift = beam.getAlpha();
37 std::vector<double> angles = scan.
coordinateAxis()->getBinCenters();
38 for (
auto& val : angles)
42 result->setWavelengthResolution(*scan.wavelengthResolution());
43 result->setAngleResolution(*scan.angleResolution());
44 return std::unique_ptr<AngularSpecScan>(result);
47 std::vector<SpecularSimulationElement> generateSimulationElements(
const Instrument& instrument,
50 std::vector<SpecularSimulationElement> result;
54 result = mangledScan(*aScan, instrument.getBeam())->generateSimulationElements();
62 for (
auto& elem : result)
63 elem.setPolarizationHandler({polarization, analyzer});
74 SpecularSimulation::SpecularSimulation() :
Simulation()
80 :
Simulation(other), m_scan(other.m_scan ? other.m_scan->clone() : nullptr),
81 m_sim_elements(other.m_sim_elements), m_cache(other.m_cache)
86 SpecularSimulation::~SpecularSimulation() =
default;
95 if (instrument().getDetectorDimension() != 1)
96 throw std::runtime_error(
"Error in SpecularSimulation::prepareSimulation: the detector was "
97 "not properly configured.");
102 size_t SpecularSimulation::numberOfSimulationElements()
const
104 return m_scan->numberOfSimulationElements();
112 if (!m_sim_elements.empty())
125 throw std::runtime_error(
126 "Error in SpecularSimulation::setScan: minimum value on coordinate axis is negative.");
128 m_scan.reset(scan.clone());
140 if (!m_scan || !m_scan->coordinateAxis())
141 throw std::runtime_error(
142 "Error in SpecularSimulation::getAlphaAxis: coordinate axis was not initialized.");
143 return m_scan->coordinateAxis();
148 return m_scan->footprintFactor();
153 return m_scan->coordinateAxis()->size();
156 void SpecularSimulation::initSimulationElementVector()
159 throw std::runtime_error(
"Error in SpecularSimulation: beam parameters were not set.");
160 m_sim_elements = generateSimulationElements(instrument(), *m_scan);
162 if (!m_cache.empty())
164 m_cache.resize(m_sim_elements.size(), 0);
167 std::unique_ptr<IComputation>
168 SpecularSimulation::generateSingleThreadedComputation(
size_t start,
size_t n_elements)
170 ASSERT(start < m_sim_elements.size() && start + n_elements <= m_sim_elements.size());
171 const auto& begin = m_sim_elements.begin() +
static_cast<long>(start);
172 return std::make_unique<SpecularComputation>(*sample(), options(), progress(), begin,
173 begin +
static_cast<long>(n_elements));
176 void SpecularSimulation::checkCache()
const
178 if (m_sim_elements.size() != m_cache.size())
179 throw std::runtime_error(
"Error in SpecularSimulation: the sizes of simulation element "
180 "vector and of its cache are different");
185 const bool zero_mean = par_distr.getDistribution()->
getMean() == 0.0;
190 const std::vector<RealParameter*> names =
192 for (
const auto par : names)
193 if (par->getName().find(
"InclinationAngle") != std::string::npos && !zero_mean)
194 throw std::runtime_error(
"Error in SpecularSimulation: parameter distribution of "
195 "beam inclination angle should have zero mean.");
198 void SpecularSimulation::initialize()
200 setName(
"SpecularSimulation");
210 void SpecularSimulation::normalize(
size_t start_ind,
size_t n_elements)
212 const double beam_intensity = getBeamIntensity();
213 if (beam_intensity == 0.0)
216 std::vector<double> footprints;
218 if (
const auto* aScan =
dynamic_cast<const AngularSpecScan*
>(m_scan.get()))
219 footprints = mangledScan(*aScan, instrument().getBeam())->footprint(start_ind, n_elements);
221 footprints = m_scan->footprint(start_ind, n_elements);
223 for (
size_t i = start_ind, k = 0; i < start_ind + n_elements; ++i, ++k) {
224 auto& element = m_sim_elements[i];
225 element.setIntensity(element.getIntensity() * beam_intensity * footprints[k]);
229 void SpecularSimulation::addBackgroundIntensity(
size_t start_ind,
size_t n_elements)
233 for (
size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
234 auto& element = m_sim_elements[i];
235 element.setIntensity(background()->addBackground(element.getIntensity()));
239 void SpecularSimulation::addDataToCache(
double weight)
242 for (
size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
243 m_cache[i] += m_sim_elements[i].getIntensity() * weight;
246 void SpecularSimulation::moveDataFromCache()
249 for (
size_t i = 0, size = m_sim_elements.size(); i < size; ++i)
250 m_sim_elements[i].setIntensity(m_cache[i]);
252 m_cache.shrink_to_fit();
255 std::vector<double> SpecularSimulation::rawResults()
const
257 std::vector<double>
result;
258 result.resize(m_sim_elements.size());
259 for (
unsigned i = 0; i < m_sim_elements.size(); ++i)
260 result[i] = m_sim_elements[i].getIntensity();
264 void SpecularSimulation::setRawResults(
const std::vector<double>& raw_data)
266 initSimulationElementVector();
267 if (raw_data.size() != m_sim_elements.size())
268 throw std::runtime_error(
"SpecularSimulation::setRawResults: size of vector passed as "
269 "argument doesn't match number of elements in this simulation");
270 for (
unsigned i = 0; i < raw_data.size(); i++)
271 m_sim_elements[i].setIntensity(raw_data[i]);
Declares AngularSpecScan class.
Defines classes representing one-dimensional distributions.
Defines class Histogram1D.
Defines interface IBackground.
Defines class ParameterPool.
Defines class PointwiseAxis.
Defines class RealParameter.
Defines class SpecularComputation.
Defines a detector for specular simulations.
Declares the class SpecularSimulationElement.
Defines class SpecularSimulation.
Defines UnitConverter1D class and derived classes.
Scan type with inclination angles as coordinate values and a unique wavelength.
virtual const IFootprintFactor * footprintFactor() const override
Returns IFootprintFactor object pointer.
virtual const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
Beam defined by wavelength, direction and intensity.
Eigen::Matrix2cd getPolarization() const
Returns the polarization density matrix (in spin basis along z-axis)
Eigen::Matrix2cd analyzerOperator() const
Return the polarization density matrix (in spin basis along z-axis)
Interface for one-dimensional axes.
virtual double getMin() const =0
Returns value of first point of axis.
const DetectionProperties & detectionProperties() const
Returns detection properties.
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'.
Pure virtual base class for all types of specular scans.
virtual std::vector< SpecularSimulationElement > generateSimulationElements() const =0
Generates simulation elements for specular simulations.
virtual const IAxis * coordinateAxis() const =0
Returns coordinate axis assigned to the data holder.
Assembles beam, detector and their relative positions with respect to the sample.
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)
void initDetector()
init detector with beam settings
void setAllTo(const T &value)
Sets content of output data to specific value.
void setRawDataVector(const std::vector< T > &data_vector)
Sets new values to raw data vector.
A parametric distribution function, for use with any model parameter.
std::string getMainParameterName() const
get the main parameter's name
Axis containing arbitrary (non-equidistant) coordinate values.
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.
virtual void prepareSimulation()
Put into a clean state for running a simulation.
virtual void transferResultsToIntensityMap()
Creates the appropriate data structure (e.g.
1D detector for specular simulations.
Main class to run a specular simulation.
const IAxis * coordinateAxis() const
Returns a pointer to coordinate axis.
SimulationResult result() const override
Returns the results of the simulation in a format that supports unit conversion and export to numpy a...
size_t intensityMapSize() const override
Returns the total number of the intensity values in the simulation result.
void setScan(const ISpecularScan &scan)
Sets chosen specular scan to the simulation.
void prepareSimulation() override
Put into a clean state for running a simulation.
const IFootprintFactor * footprintFactor() const
Returns a pointer to footprint factor holder.
static std::unique_ptr< UnitConverter1D > createUnitConverter(const ISpecularScan &handler)
Factory function to create unit converter for particular type of specular data.