BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SimDataPair.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Core/Fitting/SimDataPair.cpp
6 //! @brief Defines class SimDataPair.
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 
16 #include "Base/Math/Numeric.h"
19 #include "Device/Data/DataUtils.h"
20 
21 namespace {
22 [[noreturn]] void throwInitializationException(std::string method)
23 {
24  std::stringstream ss;
25  ss << "Error in SimDataPair::" << method << ": Trying access non-initialized data\n";
26  throw std::runtime_error(ss.str());
27 }
28 
29 std::unique_ptr<OutputData<double>> initUserWeights(const OutputData<double>& shape, double value)
30 {
31  auto result = std::make_unique<OutputData<double>>();
32  result->copyShapeFrom(shape);
33  result->setAllTo(value);
34  return result;
35 }
36 } // namespace
37 
39  std::unique_ptr<OutputData<double>> uncertainties, double user_weight)
40  : m_simulation_builder(builder)
41  , m_raw_data(data.clone())
42  , m_raw_uncertainties(std::move(uncertainties))
43 {
44  m_raw_user_weights = initUserWeights(*m_raw_data, user_weight);
45  validate();
46 }
47 
49  std::unique_ptr<OutputData<double>> uncertainties,
50  std::unique_ptr<OutputData<double>> user_weights)
51  : m_simulation_builder(builder)
52  , m_raw_data(data.clone())
53  , m_raw_uncertainties(std::move(uncertainties))
54  , m_raw_user_weights(std::move(user_weights))
55 {
56  if (!m_raw_user_weights)
57  m_raw_user_weights = initUserWeights(*m_raw_data, 1.0);
58  validate();
59 }
60 
62  : m_simulation_builder(std::move(other.m_simulation_builder))
63  , m_simulation(std::move(other.m_simulation))
64  , m_sim_data(std::move(other.m_sim_data))
65  , m_exp_data(std::move(other.m_exp_data))
66  , m_uncertainties(std::move(other.m_uncertainties))
67  , m_user_weights(std::move(other.m_user_weights))
68  , m_raw_data(std::move(other.m_raw_data))
69  , m_raw_uncertainties(std::move(other.m_raw_uncertainties))
70  , m_raw_user_weights(std::move(other.m_raw_user_weights))
71 {
72  validate();
73 }
74 
75 SimDataPair::~SimDataPair() = default;
76 
78 {
80  m_simulation->runSimulation();
81  m_sim_data = m_simulation->result();
82 
84 }
85 
87 {
88  return static_cast<bool>(m_raw_uncertainties);
89 }
90 
92 {
93  return m_simulation ? m_simulation->intensityMapSize() : 0;
94 }
95 
97 {
98  if (m_sim_data.empty())
99  throwInitializationException("simulationResult");
100  return m_sim_data;
101 }
102 
104 {
105  if (m_exp_data.empty())
106  throwInitializationException("experimentalData");
107  return m_exp_data;
108 }
109 
111 {
112  if (m_uncertainties.empty())
113  throwInitializationException("uncertainties");
114  return m_uncertainties;
115 }
116 
117 //! Returns the user uncertainties cut to the ROI area.
119 {
120  if (m_user_weights.empty())
121  throwInitializationException("userWeights");
122  return m_user_weights;
123 }
124 
125 //! Returns relative difference between simulation and experimental data.
126 
128 {
129  if (m_sim_data.size() == 0 || m_exp_data.size() == 0)
130  throwInitializationException("relativeDifference");
131 
132  SimulationResult result = m_sim_data;
133  for (size_t i = 0, size = result.size(); i < size; ++i)
134  result[i] = Numeric::GetRelativeDifference(result[i], m_exp_data[i]);
135 
136  return result;
137 }
138 
140 {
141  if (m_sim_data.size() == 0 || m_exp_data.size() == 0)
142  throwInitializationException("absoluteDifference");
143 
144  SimulationResult result = m_sim_data;
145  for (size_t i = 0, size = result.size(); i < size; ++i)
146  result[i] = Numeric::GetAbsoluteDifference(result[i], m_exp_data[i]);
147 
148  return result;
149 }
150 
151 std::vector<double> SimDataPair::experimental_array() const
152 {
153  if (m_exp_data.empty())
154  throwInitializationException("experimental_array");
155  return m_exp_data.data()->getRawDataVector();
156 }
157 
158 std::vector<double> SimDataPair::simulation_array() const
159 {
160  if (m_sim_data.empty())
161  throwInitializationException("simulation_array");
162  return m_sim_data.data()->getRawDataVector();
163 }
164 
165 std::vector<double> SimDataPair::uncertainties_array() const
166 {
167  if (m_uncertainties.empty())
168  throwInitializationException("uncertainties_array");
169  return m_uncertainties.data()->getRawDataVector();
170 }
171 
172 std::vector<double> SimDataPair::user_weights_array() const
173 {
174  if (m_user_weights.empty())
175  throwInitializationException("user_weights_array");
176  return m_user_weights.data()->getRawDataVector();
177 }
178 
180 {
181  if (m_exp_data.size() != 0 && m_uncertainties.size() != 0 && m_user_weights.size() != 0)
182  return;
183 
184  if (!m_simulation || m_sim_data.size() == 0)
185  throwInitializationException("initResultArrays");
186 
187  m_exp_data = m_simulation->convertData(*m_raw_data, true);
188 
189  if (containsUncertainties()) {
190  m_uncertainties = m_simulation->convertData(*m_raw_uncertainties, true);
191  } else {
192  const IUnitConverter& converter = m_sim_data.converter();
193  std::unique_ptr<OutputData<double>> dummy_array =
194  UnitConverterUtils::createOutputData(converter, converter.defaultUnits());
195  m_uncertainties = SimulationResult(*dummy_array, converter);
196  }
197 
198  m_user_weights = m_simulation->convertData(*m_raw_user_weights, true);
199 }
200 
202 {
204  throw std::runtime_error("Error in SimDataPair: simulation builder is empty");
205 
206  if (!m_raw_data)
207  throw std::runtime_error("Error in SimDataPair: passed experimental data array is empty");
208 
209  if (m_raw_uncertainties && !m_raw_uncertainties->hasSameShape(*m_raw_data))
210  throw std::runtime_error(
211  "Error in SimDataPair: experimental data and uncertainties have different shape.");
212 
213  if (!m_raw_user_weights || !m_raw_user_weights->hasSameShape(*m_raw_data))
214  throw std::runtime_error(
215  "Error in SimDataPair: user weights are not initialized or have invalid shape");
216 }
Defines namespace DataUtils.
std::function< std::unique_ptr< ISimulation >(const mumufit::Parameters &)> simulation_builder_t
Definition: FitTypes.h:33
Defines interface ISimulation.
Defines constants and "almost equal" in namespace Numeric.
Defines class SimDataPair.
Declares utilities for unit converters.
Interface to provide axis translations to different units for simulation output.
virtual Axes::Units defaultUnits() const =0
Holds pair of simulation/experimental data to fit.
Definition: SimDataPair.h:30
SimulationResult userWeights() const
Returns the user uncertainties cut to the ROI area.
SimulationResult m_sim_data
Current simulation results. Masked areas are nullified.
Definition: SimDataPair.h:96
std::vector< double > experimental_array() const
Returns the flattened experimental data cut to the ROI area.
std::unique_ptr< ISimulation > m_simulation
Current simulation for given set of parameters.
Definition: SimDataPair.h:93
SimulationResult absoluteDifference() const
Returns the absolute difference between simulated and experimental data cut to the ROI area.
std::unique_ptr< OutputData< double > > m_raw_user_weights
User-defined weights.
Definition: SimDataPair.h:109
std::vector< double > user_weights_array() const
Returns a flat array of user weights cut to the ROI area.
std::vector< double > uncertainties_array() const
Returns the flattened experimental uncertainties cut to the ROI area.
std::vector< double > simulation_array() const
Returns the flattened simulated intensities cut to the ROI area.
SimDataPair(simulation_builder_t builder, const OutputData< double > &data, std::unique_ptr< OutputData< double >> uncertainties, double user_weight=1.0)
Definition: SimDataPair.cpp:38
SimulationResult uncertainties() const
Returns the data uncertainties cut to the ROI area If no uncertainties present, returns zero-filled S...
SimulationResult experimentalData() const
Returns the experimental data cut to the ROI area.
bool containsUncertainties() const
Definition: SimDataPair.cpp:86
void validate() const
std::unique_ptr< OutputData< double > > m_raw_data
Raw experimental data as obtained from the user.
Definition: SimDataPair.h:105
size_t numberOfFitElements() const
Returns the number of elements in the fit area.
Definition: SimDataPair.cpp:91
SimulationResult relativeDifference() const
Returns the relative difference between simulated and experimental data cut to the ROI area.
SimulationResult simulationResult() const
Returns the result of last computed simulation.
Definition: SimDataPair.cpp:96
void initResultArrays()
SimulationResult m_uncertainties
Weights from experimental data uncertainties. Masked areas are nullified.
Definition: SimDataPair.h:100
SimulationResult m_exp_data
Experimental data cut to the ROI. Masked areas are nullified.
Definition: SimDataPair.h:98
SimulationResult m_user_weights
Manually defined (user) weights. Masked areas are nullified.
Definition: SimDataPair.h:102
void runSimulation(const mumufit::Parameters &params)
Definition: SimDataPair.cpp:77
std::unique_ptr< OutputData< double > > m_raw_uncertainties
Data uncertainties as provided by the user.
Definition: SimDataPair.h:107
simulation_builder_t m_simulation_builder
ISimulation builder from the user to construct simulation for given set of parameters.
Definition: SimDataPair.h:90
Wrapper around OutputData<double> that also provides unit conversions.
bool empty() const
size_t size() const
const IUnitConverter & converter() const
Returns underlying unit converter.
std::unique_ptr< OutputData< double > > data(Axes::Units units=Axes::Units::DEFAULT) const
A collection of fit parameters.
Definition: Parameters.h:26
double GetRelativeDifference(double a, double b)
Returns the safe relative difference, which is 2(|a-b|)/(|a|+|b|) except in special cases.
Definition: Numeric.cpp:29
double GetAbsoluteDifference(double a, double b)
Returns the absolute value of the difference between a and b.
Definition: Numeric.cpp:23
std::unique_ptr< OutputData< double > > createOutputData(const IUnitConverter &converter, Axes::Units units)
Returns zero-valued output data array in specified units.
Definition: filesystem.h:81