BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Simulation2D.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Core/Simulation/Simulation2D.cpp
6 //! @brief Implements class Simulation2D.
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 
21 
22 Simulation2D::Simulation2D() = default;
23 
24 Simulation2D::~Simulation2D() = default;
25 
27 {
30 }
31 
33 {
35 }
36 
37 void Simulation2D::addMask(const IShape2D& shape, bool mask_value)
38 {
39  instrument().detector2D().addMask(shape, mask_value);
40 }
41 
43 {
45 }
46 
47 void Simulation2D::setRegionOfInterest(double xlow, double ylow, double xup, double yup)
48 {
49  instrument().detector2D().setRegionOfInterest(xlow, ylow, xup, yup);
50 }
51 
53  : Simulation(other), m_sim_elements(other.m_sim_elements), m_cache(other.m_cache)
54 {
55 }
56 
58 {
59  if (!m_detector_context)
60  throw std::runtime_error("Error in numberOfSimulationElements(): no detector context");
61  return m_detector_context->numberOfSimulationElements();
62 }
63 
64 void Simulation2D::setDetectorParameters(size_t n_x, double x_min, double x_max, size_t n_y,
65  double y_min, double y_max)
66 {
67  instrument().detector2D().setDetectorParameters(n_x, x_min, x_max, n_y, y_min, y_max);
69 }
70 
72 {
73  instrument().setDetector(detector);
75 }
76 
77 std::unique_ptr<IComputation> Simulation2D::generateSingleThreadedComputation(size_t start,
78  size_t n_elements)
79 {
80  ASSERT(start < m_sim_elements.size() && start + n_elements <= m_sim_elements.size());
81  const auto& begin = m_sim_elements.begin() + static_cast<long>(start);
82  return std::make_unique<DWBAComputation>(*sample(), options(), progress(), begin,
83  begin + static_cast<long>(n_elements));
84 }
85 
86 std::vector<SimulationElement> Simulation2D::generateSimulationElements(const Beam& beam)
87 {
88  const double wavelength = beam.getWavelength();
89  const double alpha_i = -beam.getAlpha(); // Defined to be always positive in Beam
90  const double phi_i = beam.getPhi();
91  const Eigen::Matrix2cd beam_polarization = beam.getPolarization();
92 
93  const IDetector2D& detector = instrument().detector2D();
94  const Eigen::Matrix2cd analyzer_operator = detector.detectionProperties().analyzerOperator();
95  const size_t spec_index = detector.indexOfSpecular(beam);
96 
97  const size_t N = m_detector_context->numberOfSimulationElements();
98 
99  std::vector<SimulationElement> result;
100  result.reserve(N);
101  for (size_t element_index = 0; element_index < N; ++element_index) {
102  SimulationElement element(wavelength, alpha_i, phi_i,
103  m_detector_context->createPixel(element_index));
104  element.setPolarization(beam_polarization);
105  element.setAnalyzerOperator(analyzer_operator);
106  if (m_detector_context->detectorIndex(element_index) == spec_index)
107  element.setSpecular(true);
108  result.emplace_back(std::move(element));
109  }
110  return result;
111 }
112 
113 void Simulation2D::normalize(size_t start_ind, size_t n_elements)
114 {
115  const double beam_intensity = getBeamIntensity();
116  if (beam_intensity == 0.0)
117  return; // no normalization when beam intensity is zero
118  for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
119  SimulationElement& element = m_sim_elements[i];
120  double sin_alpha_i = std::abs(std::sin(element.getAlphaI()));
121  if (sin_alpha_i == 0.0)
122  sin_alpha_i = 1.0;
123  const double solid_angle = element.getSolidAngle();
124  element.setIntensity(element.getIntensity() * beam_intensity * solid_angle / sin_alpha_i);
125  }
126 }
127 
128 void Simulation2D::addBackgroundIntensity(size_t start_ind, size_t n_elements)
129 {
130  if (!background())
131  return;
132  for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
133  SimulationElement& element = m_sim_elements[i];
134  element.setIntensity(background()->addBackground(element.getIntensity()));
135  }
136 }
137 
138 void Simulation2D::addDataToCache(double weight)
139 {
140  if (m_sim_elements.size() != m_cache.size())
141  throw std::runtime_error("Error in Simulation2D::addDataToCache(double): cache size"
142  " not the same as element size");
143  for (unsigned i = 0; i < m_sim_elements.size(); i++)
144  m_cache[i] += m_sim_elements[i].getIntensity() * weight;
145 }
146 
148 {
149  ASSERT(!m_cache.empty());
150  if (!m_cache.empty()) {
151  for (unsigned i = 0; i < m_sim_elements.size(); i++)
152  m_sim_elements[i].setIntensity(m_cache[i]);
153  m_cache.clear();
154  }
155 }
156 
157 std::vector<double> Simulation2D::rawResults() const
158 {
159  std::vector<double> result;
160  result.resize(m_sim_elements.size());
161  for (unsigned i = 0; i < m_sim_elements.size(); ++i)
162  result[i] = m_sim_elements[i].getIntensity();
163  return result;
164 }
165 
166 void Simulation2D::setRawResults(const std::vector<double>& raw_data)
167 {
169  if (raw_data.size() != m_sim_elements.size())
170  throw std::runtime_error("Simulation2D::setRawResults: size of vector passed as "
171  "argument doesn't match number of elements in this simulation");
172  for (unsigned i = 0; i < raw_data.size(); i++)
173  m_sim_elements[i].setIntensity(raw_data[i]);
175 }
#define ASSERT(condition)
Definition: Assert.h:26
Defines class DWBAComputation.
Define DetectorContext class.
Defines class Histogram2D.
Defines interface IBackground.
Defines class Simulation2D.
Defines class SimulationElement.
Beam defined by wavelength, direction and intensity.
Definition: Beam.h:27
double getWavelength() const
Definition: Beam.h:69
Eigen::Matrix2cd getPolarization() const
Returns the polarization density matrix (in spin basis along z-axis)
Definition: Beam.cpp:123
double getAlpha() const
Definition: Beam.h:70
double getPhi() const
Definition: Beam.h:71
Eigen::Matrix2cd analyzerOperator() const
Return the polarization density matrix (in spin basis along z-axis)
Abstract 2D detector interface.
Definition: IDetector2D.h:31
std::unique_ptr< DetectorContext > createContext() const
Definition: IDetector2D.cpp:69
void setRegionOfInterest(double xlow, double ylow, double xup, double yup)
Sets rectangular region of interest with lower left and upper right corners defined.
Definition: IDetector2D.cpp:48
virtual size_t indexOfSpecular(const Beam &beam) const =0
Returns index of pixel that contains the specular wavevector.
void addMask(const IShape2D &shape, bool mask_value=true)
Adds mask of given shape to the stack of detector masks.
Definition: IDetector2D.cpp:79
void setDetectorParameters(size_t n_x, double x_min, double x_max, size_t n_y, double y_min, double y_max)
Sets detector parameters using angle ranges.
Definition: IDetector2D.cpp:35
void removeMasks()
Removes all masks from the detector.
Definition: IDetector2D.cpp:74
void maskAll()
Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
Definition: IDetector2D.cpp:85
const DetectionProperties & detectionProperties() const
Returns detection properties.
Definition: IDetector.h:93
Basic class for all shapes in 2D.
Definition: IShape2D.h:27
void setDetector(const IDetector &detector)
Sets the detector (axes can be overwritten later)
Definition: Instrument.cpp:48
IDetector2D & detector2D()
Definition: Instrument.cpp:139
Pure virtual base class of OffSpecularSimulation and GISASSimulation.
Definition: Simulation2D.h:27
size_t numberOfSimulationElements() const override
Gets the number of elements this simulation needs to calculate.
void setDetector(const IDetector2D &detector)
Sets the detector (axes can be overwritten later)
std::vector< double > m_cache
Definition: Simulation2D.h:95
std::unique_ptr< IComputation > generateSingleThreadedComputation(size_t start, size_t n_elements) override
Generate a single threaded computation for a given range of simulation elements.
std::vector< SimulationElement > m_sim_elements
Definition: Simulation2D.h:94
void moveDataFromCache() override
void normalize(size_t start_ind, size_t n_elements) override
Normalize the detector counts to beam intensity, to solid angle, and to exposure angle.
void addMask(const IShape2D &shape, bool mask_value=true)
Adds mask of given shape to the stack of detector masks.
void addBackgroundIntensity(size_t start_ind, size_t n_elements) override
void setDetectorParameters(size_t n_phi, double phi_min, double phi_max, size_t n_alpha, double alpha_min, double alpha_max)
Sets spherical detector parameters using angle ranges.
std::vector< SimulationElement > generateSimulationElements(const Beam &beam)
Generate simulation elements for given beam.
void setRawResults(const std::vector< double > &raw_data) override
std::unique_ptr< DetectorContext > m_detector_context
Definition: Simulation2D.h:100
void maskAll()
Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
void removeMasks()
removes all masks from the detector
virtual void initUnitConverter()
Definition: Simulation2D.h:69
void prepareSimulation() override
Put into a clean state for running a simulation.
~Simulation2D() override
std::vector< double > rawResults() const override
void setRegionOfInterest(double xlow, double ylow, double xup, double yup)
Sets rectangular region of interest with lower left and upper right corners defined.
void addDataToCache(double weight) override
Data stucture containing both input and output of a single detector cell.
void setSpecular(bool is_specular)
Set specularity indication on/off.
double getIntensity() const
double getSolidAngle() const
double getAlphaI() const
void setIntensity(double intensity)
void setPolarization(const Eigen::Matrix2cd &polarization)
Sets the polarization density matrix (in spin basis along z-axis)
void setAnalyzerOperator(const Eigen::Matrix2cd &polarization_operator)
Sets the polarization analyzer operator (in spin basis along z-axis)
Pure virtual base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
Definition: Simulation.h:38
const Instrument & instrument() const
Definition: Simulation.h:55
virtual void updateIntensityMap()
Definition: Simulation.h:115
ProgressHandler & progress()
Definition: Simulation.h:121
const IBackground * background() const
Definition: Simulation.h:75
virtual void initSimulationElementVector()=0
Initializes the vector of Simulation elements.
virtual void prepareSimulation()
Put into a clean state for running a simulation.
Definition: Simulation.cpp:189
virtual void transferResultsToIntensityMap()
Creates the appropriate data structure (e.g.
Definition: Simulation.h:110
const MultiLayer * sample() const
Definition: Simulation.cpp:247
double getBeamIntensity() const
Definition: Simulation.cpp:178
virtual SimulationResult result() const =0
Returns the results of the simulation in a format that supports unit conversion and export to numpy a...
const SimulationOptions & options() const
Definition: Simulation.h:120