BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
IntensityDataFunctions Namespace Reference

Functions

double RelativeDifference (const SimulationResult &dat, const SimulationResult &ref)
 
double getRelativeDifference (const OutputData< double > &dat, const OutputData< double > &ref)
 
bool checkRelativeDifference (const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)
 
double getRelativeDifference (const IHistogram &dat, const IHistogram &ref)
 
double coordinateToBinf (double coordinate, const IAxis &axis)
 
double coordinateFromBinf (double value, const IAxis &axis)
 
void coordinateToBinf (double &x, double &y, const OutputData< double > &data)
 
void coordinateFromBinf (double &x, double &y, const OutputData< double > &data)
 
std::vector< std::vector< double > > create2DArrayfromOutputData (const OutputData< double > &data)
 
std::vector< std::vector< double > > FT2DArray (const std::vector< std::vector< double >> &signal)
 
std::unique_ptr< OutputData< double > > createRelativeDifferenceData (const OutputData< double > &data, const OutputData< double > &reference)
 
std::unique_ptr< OutputData< double > > createRearrangedDataSet (const OutputData< double > &data, int n)
 
std::unique_ptr< OutputData< double > > createClippedDataSet (const OutputData< double > &origin, double x1, double y1, double x2, double y2)
 
std::unique_ptr< OutputData< double > > createOutputDatafrom2DArray (const std::vector< std::vector< double >> &array_2d)
 
std::unique_ptr< OutputData< double > > createFFT (const OutputData< double > &data)
 

Detailed Description

Functions to work with intensity data.

Function Documentation

◆ RelativeDifference()

double IntensityDataFunctions::RelativeDifference ( const SimulationResult dat,
const SimulationResult ref 
)

Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )

Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon )

Definition at line 28 of file IntensityDataFunctions.cpp.

30 {
31  if (dat.size() != ref.size())
32  throw std::runtime_error("Error in IntensityDataFunctions::RelativeDifference: "
33  "different number of elements");
34  if (dat.empty())
35  return 0.0;
36  double sum_of_diff = 0.0;
37  for (size_t i = 0; i < dat.size(); ++i) {
38  sum_of_diff += Numeric::GetRelativeDifference(dat[i], ref[i]);
39  }
40  return sum_of_diff / dat.size();
41 }
bool empty() const
size_t size() const
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:32

References SimulationResult::empty(), Numeric::GetRelativeDifference(), and SimulationResult::size().

Here is the call graph for this function:

◆ getRelativeDifference() [1/2]

double IntensityDataFunctions::getRelativeDifference ( const OutputData< double > &  dat,
const OutputData< double > &  ref 
)

Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).

Definition at line 44 of file IntensityDataFunctions.cpp.

46 {
47  if (!dat.hasSameDimensions(ref))
49  "IntensityDataFunctions::getRelativeDifference() -> "
50  "Error. Different dimensions of data and reference.");
51 
52  double diff = 0.0;
53  for (size_t i = 0; i < dat.getAllocatedSize(); ++i)
54  diff += Numeric::GetRelativeDifference(dat[i], ref[i]);
55  diff /= dat.getAllocatedSize();
56 
57  if (std::isnan(diff))
58  throw Exceptions::RuntimeErrorException("diff=NaN!");
59  return diff;
60 }
bool hasSameDimensions(const OutputData< U > &right) const
Returns true if object have same dimensions and number of axes bins.
Definition: OutputData.h:578
size_t getAllocatedSize() const
Returns total size of data buffer (product of bin number in every dimension).
Definition: OutputData.h:62

References OutputData< T >::getAllocatedSize(), Numeric::GetRelativeDifference(), and OutputData< T >::hasSameDimensions().

Referenced by checkRelativeDifference(), and getRelativeDifference().

Here is the call graph for this function:

◆ checkRelativeDifference()

bool IntensityDataFunctions::checkRelativeDifference ( const OutputData< double > &  dat,
const OutputData< double > &  ref,
const double  threshold 
)

Returns true is relative difference is below threshold; prints informative output.

Definition at line 69 of file IntensityDataFunctions.cpp.

72 {
73  const double diff = getRelativeDifference(dat, ref);
74  if (diff > threshold) {
75  std::cerr << " => FAILED: relative deviation of dat from ref is " << diff
76  << ", above given threshold " << threshold << "\n";
77  return false;
78  }
79  if (diff)
80  std::cerr << " => OK: relative deviation of dat from ref is " << diff
81  << ", within given threshold " << threshold << "\n";
82  else
83  std::cout << " => OK: dat = ref\n";
84  return true;
85 }
double getRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref)
Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).

References getRelativeDifference().

Here is the call graph for this function:

◆ getRelativeDifference() [2/2]

double IntensityDataFunctions::getRelativeDifference ( const IHistogram dat,
const IHistogram ref 
)

Definition at line 62 of file IntensityDataFunctions.cpp.

63 {
64  return getRelativeDifference(*std::unique_ptr<OutputData<double>>(dat.getData().meanValues()),
65  *std::unique_ptr<OutputData<double>>(ref.getData().meanValues()));
66 }
const OutputData< CumulativeValue > & getData() const
Definition: IHistogram.h:92
OutputData< double > * meanValues() const
Definition: OutputData.h:279

References IHistogram::getData(), getRelativeDifference(), and OutputData< T >::meanValues().

Here is the call graph for this function:

◆ coordinateToBinf() [1/2]

double IntensityDataFunctions::coordinateToBinf ( double  coordinate,
const IAxis axis 
)

Transforms coordinate on axis into the bin-fraction-coordinate.

Definition at line 189 of file IntensityDataFunctions.cpp.

190 {
191  size_t index = axis.findClosestIndex(coordinate);
192  Bin1D bin = axis.getBin(index);
193  double f = (coordinate - bin.m_lower) / bin.getBinSize();
194  return static_cast<double>(index) + f;
195 }
virtual size_t findClosestIndex(double value) const =0
find bin index which is best match for given value
virtual Bin1D getBin(size_t index) const =0
retrieve a 1d bin for the given index
Definition: Bin.h:20
double getBinSize() const
Definition: Bin.h:26
double m_lower
lower bound of the bin
Definition: Bin.h:23

References IAxis::findClosestIndex(), IAxis::getBin(), Bin1D::getBinSize(), and Bin1D::m_lower.

Referenced by coordinateToBinf().

Here is the call graph for this function:

◆ coordinateFromBinf() [1/2]

double IntensityDataFunctions::coordinateFromBinf ( double  value,
const IAxis axis 
)

Transforms bin-fraction-coordinate into axis coordinate.

Definition at line 197 of file IntensityDataFunctions.cpp.

198 {
199  int index = static_cast<int>(value);
200 
201  double result(0);
202  if (index < 0) {
203  Bin1D bin = axis.getBin(0);
204  result = bin.m_lower + value * bin.getBinSize();
205  } else if (index >= static_cast<int>(axis.size())) {
206  Bin1D bin = axis.getBin(axis.size() - 1);
207  result = bin.m_upper + (value - axis.size()) * bin.getBinSize();
208  } else {
209  Bin1D bin = axis.getBin(static_cast<size_t>(index));
210  result = bin.m_lower + (value - static_cast<double>(index)) * bin.getBinSize();
211  }
212 
213  return result;
214 }
virtual size_t size() const =0
retrieve the number of bins
double m_upper
upper bound of the bin
Definition: Bin.h:24

References IAxis::getBin(), Bin1D::getBinSize(), Bin1D::m_lower, Bin1D::m_upper, and IAxis::size().

Referenced by coordinateFromBinf().

Here is the call graph for this function:

◆ coordinateToBinf() [2/2]

void IntensityDataFunctions::coordinateToBinf ( double &  x,
double &  y,
const OutputData< double > &  data 
)

Transforms x,y coordinate from OutputData axes coordinates to bin-fraction-coordinates.

Definition at line 216 of file IntensityDataFunctions.cpp.

217 {
218  x = coordinateToBinf(x, data.getAxis(0));
219  y = coordinateToBinf(y, data.getAxis(1));
220 }
const IAxis & getAxis(size_t serial_number) const
returns axis with given serial number
Definition: OutputData.h:314
double coordinateToBinf(double coordinate, const IAxis &axis)
Transforms coordinate on axis into the bin-fraction-coordinate.

References coordinateToBinf(), and OutputData< T >::getAxis().

Here is the call graph for this function:

◆ coordinateFromBinf() [2/2]

void IntensityDataFunctions::coordinateFromBinf ( double &  x,
double &  y,
const OutputData< double > &  data 
)

Transforms x,y coordinate from bin-fraction-coordinates to OutputData's axes coordinates.

Definition at line 222 of file IntensityDataFunctions.cpp.

224 {
225  x = coordinateFromBinf(x, data.getAxis(0));
226  y = coordinateFromBinf(y, data.getAxis(1));
227 }
double coordinateFromBinf(double value, const IAxis &axis)
Transforms bin-fraction-coordinate into axis coordinate.

References coordinateFromBinf(), and OutputData< T >::getAxis().

Here is the call graph for this function:

◆ create2DArrayfromOutputData()

std::vector< std::vector< double > > IntensityDataFunctions::create2DArrayfromOutputData ( const OutputData< double > &  data)

Creates a vector of vectors of double (2D Array) from OutputData.

Definition at line 230 of file IntensityDataFunctions.cpp.

231 {
232  if (data.getRank() != 2)
234  "IntensityDataFunctions::create2DArrayfromOutputData() -> "
235  "Error! Works only on two-dimensional data");
236 
237  std::vector<std::vector<double>> array_2d;
238  std::vector<double> row_vec; // row vector for constructing each row of 2D array
239 
240  size_t nrows = data.getAxis(0).size();
241  size_t ncols = data.getAxis(1).size();
242 
243  size_t it = 0; // iterator of 'data'
244  for (size_t row = 0; row < nrows; row++) {
245  row_vec.clear();
246  for (size_t col = 0; col < ncols; col++) {
247  row_vec.push_back(data[it]);
248  it++;
249  }
250  array_2d.push_back(row_vec);
251  }
252 
253  return array_2d;
254 }
size_t getRank() const
Returns number of dimensions.
Definition: OutputData.h:59

References OutputData< T >::getAxis(), OutputData< T >::getRank(), and IAxis::size().

Referenced by createFFT().

Here is the call graph for this function:

◆ FT2DArray()

std::vector< std::vector< double > > IntensityDataFunctions::FT2DArray ( const std::vector< std::vector< double >> &  signal)

Creates a Fourier Transform of a 2D Array (vector of vectors).

Definition at line 257 of file IntensityDataFunctions.cpp.

258 {
259  FourierTransform ft;
260  std::vector<std::vector<double>> fft_array;
261  ft.fft(signal, fft_array);
262  // shifting low frequency to center of array
263  ft.fftshift(fft_array);
264 
265  return fft_array;
266 }
Fourier transform of vectors (in 1D or 2D) using Fast Fourier Transform (fftw package).
void fft(const double1d_t &source, double1d_t &result)
FT in 1D.
void fftshift(double1d_t &result)
Shift low frequency to the center of 1D FT array.

References FourierTransform::fft(), and FourierTransform::fftshift().

Referenced by createFFT().

Here is the call graph for this function:

◆ createRelativeDifferenceData()

std::unique_ptr< OutputData< double > > IntensityDataFunctions::createRelativeDifferenceData ( const OutputData< double > &  data,
const OutputData< double > &  reference 
)

Definition at line 88 of file IntensityDataFunctions.cpp.

90 {
91  if (!data.hasSameDimensions(reference))
93  "IntensityDataFunctions::createRelativeDifferenceData() -> "
94  "Error. Different dimensions of data and reference.");
95  std::unique_ptr<OutputData<double>> result(reference.clone());
96  for (size_t i = 0; i < result->getAllocatedSize(); ++i)
97  (*result)[i] = Numeric::GetRelativeDifference(data[i], reference[i]);
98  return result;
99 }
OutputData * clone() const
Definition: OutputData.h:253

References OutputData< T >::clone(), Numeric::GetRelativeDifference(), and OutputData< T >::hasSameDimensions().

Here is the call graph for this function:

◆ createRearrangedDataSet()

std::unique_ptr< OutputData< double > > IntensityDataFunctions::createRearrangedDataSet ( const OutputData< double > &  data,
int  n 
)

Returns new object with input data rotated by n*90 deg counterclockwise (n > 0) or clockwise (n < 0) Axes are swapped if the data is effectively rotated by 90 or 270 degrees Applicable to 2D arrays only.

Definition at line 102 of file IntensityDataFunctions.cpp.

103 {
104  if (data.getRank() != 2)
105  throw Exceptions::LogicErrorException("IntensityDataFunctions::rotateDataByN90Deg()"
106  " -> Error! Works only on two-dimensional data");
107  n = (4 + n % 4) % 4;
108  if (n == 0)
109  return std::unique_ptr<OutputData<double>>(data.clone());
110  std::unique_ptr<OutputData<double>> output(new OutputData<double>());
111 
112  // swapping axes if necessary
113  const IAxis& x_axis = data.getAxis(0);
114  const IAxis& y_axis = data.getAxis(1);
115  output->addAxis(n == 2 ? x_axis : y_axis);
116  output->addAxis(n == 2 ? y_axis : x_axis);
117 
118  // creating index mapping
119  std::function<void(std::vector<int>&)> index_mapping;
120  if (n == 2) {
121  const int end_bin_x = static_cast<int>(x_axis.size()) - 1;
122  const int end_bin_y = static_cast<int>(y_axis.size()) - 1;
123  index_mapping = [end_bin_x, end_bin_y](std::vector<int>& inds) {
124  inds[0] = end_bin_x - inds[0];
125  inds[1] = end_bin_y - inds[1];
126  };
127  } else {
128  const size_t rev_axis_i = n % 3;
129  const size_t end_bin = data.getAxis(rev_axis_i).size() - 1;
130  index_mapping = [rev_axis_i, end_bin](std::vector<int>& inds) {
131  const int tmp_index = inds[rev_axis_i];
132  inds[rev_axis_i] = inds[rev_axis_i ^ 1];
133  inds[rev_axis_i ^ 1] = static_cast<int>(end_bin) - tmp_index;
134  };
135  }
136 
137  for (size_t index = 0, size = data.getAllocatedSize(); index < size; ++index) {
138  std::vector<int> axis_inds = data.getAxesBinIndices(index);
139  index_mapping(axis_inds);
140  size_t output_index = output->toGlobalIndex(
141  {static_cast<unsigned>(axis_inds[0]), static_cast<unsigned>(axis_inds[1])});
142  (*output)[output_index] = data[index];
143  }
144  return output;
145 }
Interface for one-dimensional axes.
Definition: IAxis.h:25
std::vector< int > getAxesBinIndices(size_t global_index) const
Returns vector of axes indices for given global index.
Definition: OutputData.h:356

References OutputData< T >::clone(), OutputData< T >::getAllocatedSize(), OutputData< T >::getAxesBinIndices(), OutputData< T >::getAxis(), OutputData< T >::getRank(), and IAxis::size().

Here is the call graph for this function:

◆ createClippedDataSet()

std::unique_ptr< OutputData< double > > IntensityDataFunctions::createClippedDataSet ( const OutputData< double > &  origin,
double  x1,
double  y1,
double  x2,
double  y2 
)

Returns new IntensityData objects which axes clipped to represent the specified rectangle.

Definition at line 148 of file IntensityDataFunctions.cpp.

150 {
151  if (origin.getRank() != 2)
152  throw Exceptions::LogicErrorException("IntensityDataFunctions::createClippedData()"
153  " -> Error! Works only on two-dimensional data");
154 
155  std::unique_ptr<OutputData<double>> result(new OutputData<double>);
156  for (size_t i_axis = 0; i_axis < origin.getRank(); i_axis++) {
157  const IAxis& axis = origin.getAxis(i_axis);
158  IAxis* new_axis;
159  if (i_axis == 0)
160  new_axis = axis.createClippedAxis(x1, x2);
161  else
162  new_axis = axis.createClippedAxis(y1, y2);
163  result->addAxis(*new_axis);
164  delete new_axis;
165  }
166  result->setAllTo(0.0);
167 
168  OutputData<double>::const_iterator it_origin = origin.begin();
169  OutputData<double>::iterator it_result = result->begin();
170  while (it_origin != origin.end()) {
171  double x = origin.getAxisValue(it_origin.getIndex(), 0);
172  double y = origin.getAxisValue(it_origin.getIndex(), 1);
173  if (result->getAxis(0).contains(x) && result->getAxis(1).contains(y)) {
174  *it_result = *it_origin;
175  ++it_result;
176  }
177  ++it_origin;
178  }
179 
180  return result;
181 }
virtual IAxis * createClippedAxis(double left, double right) const
Creates a new clipped axis.
Definition: IAxis.cpp:34
iterator end()
Returns read/write iterator that points to the one past last element.
Definition: OutputData.h:96
iterator begin()
Returns read/write iterator that points to the first element.
Definition: OutputData.h:344
double getAxisValue(size_t global_index, size_t i_selected_axis) const
Returns the value of selected axis for given global_index.
Definition: OutputData.h:433

References OutputData< T >::begin(), IAxis::createClippedAxis(), OutputData< T >::end(), OutputData< T >::getAxis(), OutputData< T >::getAxisValue(), and OutputData< T >::getRank().

Here is the call graph for this function:

◆ createOutputDatafrom2DArray()

std::unique_ptr< OutputData< double > > IntensityDataFunctions::createOutputDatafrom2DArray ( const std::vector< std::vector< double >> &  array_2d)

Creates OutputData from a 2D Array.

Definition at line 268 of file IntensityDataFunctions.cpp.

270 {
271  std::unique_ptr<OutputData<double>> result(new OutputData<double>);
272  size_t nrows = array_2d.size();
273  size_t ncols = array_2d[0].size();
274 
275  result->addAxis("x", nrows, 0.0, double(nrows));
276  result->addAxis("y", ncols, 0.0, double(ncols));
277  std::vector<unsigned> axes_indices(2);
278  for (unsigned row = 0; row < nrows; row++) {
279  for (unsigned col = 0; col < ncols; col++) {
280  axes_indices[0] = row;
281  axes_indices[1] = col;
282  size_t global_index = result->toGlobalIndex(axes_indices);
283  (*result)[global_index] = array_2d[row][col];
284  }
285  }
286 
287  return result;
288 }

Referenced by createFFT().

◆ createFFT()

std::unique_ptr< OutputData< double > > IntensityDataFunctions::createFFT ( const OutputData< double > &  data)

Creates Fourier Transform (OutputData format) of intensity map (OutputData format).

Definition at line 291 of file IntensityDataFunctions.cpp.

292 {
294  auto fft_array_2d = IntensityDataFunctions::FT2DArray(array_2d);
296 }
std::vector< std::vector< double > > create2DArrayfromOutputData(const OutputData< double > &data)
Creates a vector of vectors of double (2D Array) from OutputData.
std::unique_ptr< OutputData< double > > createOutputDatafrom2DArray(const std::vector< std::vector< double >> &array_2d)
Creates OutputData from a 2D Array.
std::vector< std::vector< double > > FT2DArray(const std::vector< std::vector< double >> &signal)
Creates a Fourier Transform of a 2D Array (vector of vectors).

References create2DArrayfromOutputData(), createOutputDatafrom2DArray(), and FT2DArray().

Here is the call graph for this function: