BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
QzScan.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sim/Scan/QzScan.cpp
6 //! @brief Implements QzScan class.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #include "Sim/Scan/QzScan.h"
16 #include "Base/Axis/FixedBinAxis.h"
19 #include "Device/Pol/PolFilter.h"
23 #include <algorithm>
24 
26  : m_qs(std::move(qs_nm))
27  , m_resolution(ScanResolution::scanEmptyResolution())
28 {
29  std::vector<double> axis_values = m_qs->binCenters();
30  if (!std::is_sorted(axis_values.begin(), axis_values.end()))
31  throw std::runtime_error("Error in QzScan::checkInitialization: q-vector values shall "
32  "be sorted in ascending order.");
33 
34  if (axis_values.front() < 0)
35  throw std::runtime_error("Error in QzScan::checkInitialization: q-vector values are out "
36  "of acceptable range.");
37 }
38 
39 QzScan::QzScan(std::vector<double> qs_nm)
40  : QzScan(new PointwiseAxis("qs", std::move(qs_nm)))
41 {
42 }
43 
44 QzScan::QzScan(const IAxis& qs_nm)
45  : QzScan(qs_nm.clone())
46 {
47 }
48 
49 QzScan::QzScan(int nbins, double qz_min, double qz_max)
50  : QzScan(new FixedBinAxis("qs", nbins, qz_min, qz_max))
51 {
52 }
53 
54 QzScan::~QzScan() = default;
55 
57 {
58  auto* result = new QzScan(*m_qs);
59  result->setQResolution(*m_resolution);
60  result->setOffset(m_offset);
61  // TODO merge with same code in AlphaScan
63  result->m_beamPolarization.reset(new R3(*m_beamPolarization));
64  if (m_polAnalyzer)
65  result->m_polAnalyzer.reset(new PolFilter(*m_polAnalyzer));
66  return result;
67 }
68 
69 //! Generates simulation elements for specular simulations
70 std::vector<SpecularElement> QzScan::generateElements() const
71 {
72  const std::vector<double> qz = generateQzVector();
73 
74  std::vector<SpecularElement> result;
75  result.reserve(qz.size());
76  for (size_t i = 0, size = qz.size(); i < size; ++i)
77  result.emplace_back(
78  SpecularElement::FromQzScan(-(qz[i] + m_offset) / 2.0, polMatrices(), qz[i] >= 0));
79 
80  return result;
81 }
82 
83 std::vector<double> QzScan::footprint(size_t i, size_t n_elements) const
84 {
85  if (i + n_elements > numberOfElements())
86  throw std::runtime_error("Error in QzScan::footprint: given index exceeds the "
87  "number of simulation elements");
88  return std::vector<double>(n_elements, 1.0);
89 }
90 
91 //! Returns the number of simulation elements
93 {
94  return m_qs->size() * m_resolution->nSamples();
95 }
96 
98 {
100 }
101 
102 std::vector<double> QzScan::createIntensities(const std::vector<SpecularElement>& eles) const
103 {
104  const size_t axis_size = m_qs->size();
105  std::vector<double> result(axis_size, 0.0);
106 
107  const auto samples = applyQResolution();
108 
109  size_t elem_pos = 0;
110  for (size_t i = 0; i < axis_size; ++i) {
111  double& current = result[i];
112  for (size_t j = 0, size = samples[i].size(); j < size; ++j) {
113  current += eles[elem_pos].intensity() * samples[i][j].weight;
114  ++elem_pos;
115  }
116  }
117  return result;
118 }
119 
120 void QzScan::setQResolution(const ScanResolution& resolution)
121 {
122  m_resolution.reset(resolution.clone());
123 }
124 
125 void QzScan::setRelativeQResolution(const IRangedDistribution& distr, double rel_dev)
126 {
127  std::unique_ptr<ScanResolution> resolution(
130 }
131 
133  const std::vector<double>& rel_dev)
134 {
135  std::unique_ptr<ScanResolution> resolution(
138 }
139 
140 void QzScan::setAbsoluteQResolution(const IRangedDistribution& distr, double std_dev)
141 {
142  std::unique_ptr<ScanResolution> resolution(
145 }
146 
148  const std::vector<double>& std_dev)
149 {
150  std::unique_ptr<ScanResolution> resolution(
153 }
154 
155 std::vector<double> QzScan::generateQzVector() const
156 {
157  const auto samples = applyQResolution();
158 
159  std::vector<double> result;
160  result.reserve(numberOfElements());
161  for (size_t i = 0, size_out = samples.size(); i < size_out; ++i)
162  for (size_t j = 0, size_in = samples[i].size(); j < size_in; ++j)
163  result.push_back(samples[i][j].value);
164  return result;
165 }
166 
167 std::vector<std::vector<ParameterSample>> QzScan::applyQResolution() const
168 {
169  return m_resolution->generateSamples(m_qs->binCenters());
170 }
Defines CoordSystem1D class and derived classes.
Defines class FixedBinAxis.
Defines class PointwiseAxis.
Defines class DetectionProperties.
Declares QzScan class.
Defines classes representing ranged one-dimensional distributions.
Defines scan resolution class.
Declares the class SpecularElement.
Abstract base class to support coordinate transforms and axis labels for 1D scans....
Definition: CoordSystem1D.h:33
Axis with fixed bin size.
Definition: FixedBinAxis.h:23
Abstract base class for one-dimensional axes.
Definition: IAxis.h:27
Interface for one-dimensional ranged distributions. All derived distributions allow for generating sa...
std::unique_ptr< R3 > m_beamPolarization
Bloch vector encoding the beam's polarization.
Definition: ISpecularScan.h:77
PolMatrices polMatrices() const
std::unique_ptr< PolFilter > m_polAnalyzer
Definition: ISpecularScan.h:78
Axis containing arbitrary (non-equidistant) coordinate values. Lower boundary of the first bin and up...
Definition: PointwiseAxis.h:33
Detector properties (efficiency, transmission).
Definition: PolFilter.h:27
Scan type with z-components of scattering vector as coordinate values. Wavelength and incident angles...
Definition: QzScan.h:28
double m_offset
Definition: QzScan.h:100
void setRelativeQResolution(const IRangedDistribution &distr, double rel_dev)
Definition: QzScan.cpp:125
~QzScan() override
std::vector< double > createIntensities(const std::vector< SpecularElement > &eles) const override
Returns intensity vector corresponding to convolution of given simulation elements.
Definition: QzScan.cpp:102
QzScan(std::vector< double > qs_nm)
Accepts qz-value vector (in inverse nm)
Definition: QzScan.cpp:39
void setQResolution(const ScanResolution &resolution)
Sets q resolution values via ScanResolution object.
Definition: QzScan.cpp:120
const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
Definition: QzScan.h:51
void setAbsoluteQResolution(const IRangedDistribution &distr, double std_dev)
Definition: QzScan.cpp:140
CoordSystem1D * createCoordSystem() const override
Definition: QzScan.cpp:97
std::vector< SpecularElement > generateElements() const override
Generates simulation elements for specular simulations.
Definition: QzScan.cpp:70
const std::unique_ptr< IAxis > m_qs
Definition: QzScan.h:97
size_t numberOfElements() const override
Returns the number of simulation elements.
Definition: QzScan.cpp:92
std::unique_ptr< ScanResolution > m_resolution
Definition: QzScan.h:98
QzScan * clone() const override
Definition: QzScan.cpp:56
const ScanResolution * resolution() const
Definition: QzScan.h:42
std::vector< std::vector< ParameterSample > > applyQResolution() const
Definition: QzScan.cpp:167
std::vector< double > generateQzVector() const
Definition: QzScan.cpp:155
std::vector< double > footprint(size_t i, size_t n_elements) const override
Returns footprint correction factor for a range of simulation elements of size n_elements and startin...
Definition: QzScan.cpp:83
Container for reflectivity resolution data.
static ScanResolution * scanAbsoluteResolution(const IRangedDistribution &distr, double stddev)
ScanResolution * clone() const override=0
static ScanResolution * scanRelativeResolution(const IRangedDistribution &distr, double stddev)
static SpecularElement FromQzScan(double kz, const PolMatrices &polMatrices, bool computable)
Conversion of axis units for the case of q-defined reflectometry.
Definition: CoordSystem1D.h:99