forked from npshub/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Diffraction.cpp
163 lines (137 loc) · 4.49 KB
/
Diffraction.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidKernel/Diffraction.h"
#include <algorithm>
#include <cmath>
namespace Mantid {
namespace Kernel {
namespace Diffraction {
double calcTofMin(const double difc, const double difa, const double tzero, const double tofmin) {
if (difa == 0.) {
if (tzero != 0.) {
// check for negative d-spacing
return std::max<double>(tzero, tofmin);
}
} else if (difa > 0.) {
// check for imaginary part in quadratic equation
return std::max<double>(tzero - .25 * difc * difc / difa, tofmin);
}
// everything else is fine so just return supplied tofmin
return tofmin;
}
/**
* Returns the maximum TOF that can be used or tofmax. Whichever is smaller. In
* the case when this is a negative number, just return 0.
*/
double calcTofMax(const double difc, const double difa, const double tzero, const double tofmax) {
if (difa < 0.) {
// check for imaginary part in quadratic equation
if (tzero > 0.) {
// rather than calling abs multiply difa by -1
return std::min<double>(tzero + .25 * difc * difc / difa, tofmax);
} else {
return 0.;
}
}
// everything else is fine so just return supplied tofmax
return tofmax;
}
// ----------------------------------------------------------------------------
// convert from d-spacing to time-of-flight
namespace { // anonymous namespace
/// Applies the equation d=(TOF-tzero)/difc
struct tof_to_d_difc_only {
explicit tof_to_d_difc_only(const double difc) : factor(1. / difc) {}
double operator()(const double tof) const { return factor * tof; }
/// 1./difc
double factor;
};
/// Applies the equation d=(TOF-tzero)/difc
struct tof_to_d_difc_and_tzero {
explicit tof_to_d_difc_and_tzero(const double difc, const double tzero)
: factor(1. / difc), offset(-1. * tzero / difc) {}
double operator()(const double tof) const { return factor * tof + offset; }
/// 1./difc
double factor;
/// -tzero/difc
double offset;
};
struct tof_to_d {
explicit tof_to_d(const double difc, const double difa, const double tzero) {
factor1 = -0.5 * difc / difa;
factor2 = 1. / difa;
factor3 = (factor1 * factor1) - (tzero / difa);
}
double operator()(const double tof) const {
double second = std::sqrt((tof * factor2) + factor3);
if (second < factor1)
return factor1 - second;
else {
return factor1 + second;
}
}
/// -0.5*difc/difa
double factor1;
/// 1/difa
double factor2;
/// (0.5*difc/difa)^2 - (tzero/difa)
double factor3;
};
} // anonymous namespace
std::function<double(double)> getTofToDConversionFunc(const double difc, const double difa, const double tzero) {
if (difa == 0.) {
if (tzero == 0.) {
return tof_to_d_difc_only(difc);
} else {
return tof_to_d_difc_and_tzero(difc, tzero);
}
} else { // difa != 0.
return tof_to_d(difc, difa, tzero);
}
}
// ----------------------------------------------------------------------------
// convert from d-spacing to time-of-flight
namespace { // anonymous namespace
struct d_to_tof_difc_only {
explicit d_to_tof_difc_only(const double difc) { this->difc = difc; }
double operator()(const double dspacing) const { return difc * dspacing; }
double difc;
};
struct d_to_tof_difc_and_tzero {
explicit d_to_tof_difc_and_tzero(const double difc, const double tzero) {
this->difc = difc;
this->tzero = tzero;
}
double operator()(const double dspacing) const { return difc * dspacing + tzero; }
double difc;
double tzero;
};
struct d_to_tof {
explicit d_to_tof(const double difc, const double difa, const double tzero) {
this->difc = difc;
this->difa = difa;
this->tzero = tzero;
}
double operator()(const double dspacing) const { return difc * dspacing + difa * dspacing * dspacing + tzero; }
double difc;
double difa;
double tzero;
};
} // anonymous namespace
std::function<double(double)> getDToTofConversionFunc(const double difc, const double difa, const double tzero) {
if (difa == 0.) {
if (tzero == 0.)
return d_to_tof_difc_only(difc);
else
return d_to_tof_difc_and_tzero(difc, tzero);
} else {
return d_to_tof(difc, difa, tzero);
}
}
} // namespace Diffraction
} // namespace Kernel
} // namespace Mantid