17#include "MantidTypes/SpectrumDefinition.h"
19#include <boost/math/special_functions/bessel.hpp>
36 this->declareParameter(
"Intensity", 1.0,
"scaling factor");
37 this->declareParameter(
"Radius", 2.0,
"Sphere radius, in Angstroms");
38 this->declareParameter(
"Diffusion", 0.05,
39 "Diffusion coefficient, in units of "
40 "A^2*THz, if energy in meV, or A^2*PHz "
42 this->declareParameter(
"Shift", 0.0,
"Shift in domain");
58 double xvalues[] = {2.081576, 3.342094, 4.493409, 4.514100, 5.646704, 5.940370, 6.756456, 7.289932, 7.725252,
59 7.851078, 8.583755, 8.934839, 9.205840, 9.840446, 10.010371, 10.613855, 10.904122, 11.070207,
60 11.079418, 11.972730, 12.143204, 12.279334, 12.404445, 13.202620, 13.295564, 13.472030, 13.846112,
61 14.066194, 14.258341, 14.590552, 14.651263, 15.244514, 15.310887, 15.579236, 15.819216, 15.863222,
62 16.360674, 16.609346, 16.977550, 17.042902, 17.117506, 17.220755, 17.408034, 17.947180, 18.127564,
63 18.356318, 18.453241, 18.468148, 18.742646, 19.262710, 19.270294, 19.496524, 19.581889, 19.862424,
64 20.221857, 20.371303, 20.406581, 20.538074, 20.559428, 20.795967, 21.231068, 21.537120, 21.578053,
65 21.666607, 21.840012, 21.899697, 21.999955, 22.578058, 22.616601, 22.662493, 23.082796, 23.106568,
66 23.194996, 23.390490, 23.519453, 23.653839, 23.783192, 23.906450, 24.360789, 24.382038, 24.474825,
67 24.689873, 24.850085, 24.899636, 25.052825, 25.218652, 25.561873, 25.604057, 25.724794, 25.846084,
68 26.012188, 26.283265, 26.516603, 26.552589, 26.666054, 26.735177, 26.758685, 26.837518};
70 size_t lvalues[] = {1, 2, 0, 3, 4, 1, 5, 2, 0, 6, 3, 7, 1, 4, 8, 2, 0, 5, 9, 3, 10, 6, 1, 11, 4,
71 7, 2, 0, 12, 5, 8, 3, 13, 1, 9, 6, 14, 4, 10, 2, 7, 0, 15, 5, 11, 8, 16, 3, 1, 6,
72 12, 17, 9, 4, 2, 0, 13, 18, 7, 10, 5, 14, 19, 3, 8, 1, 11, 6, 20, 15, 4, 9, 12, 2, 0,
73 21, 16, 7, 10, 13, 5, 22, 3, 17, 1, 8, 14, 11, 23, 6, 18, 4, 9, 2, 0, 15, 24, 12};
75 size_t nvalues[] = {0, 0, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0, 2, 1, 0, 2, 3, 1, 0, 2, 0, 1, 3, 0, 2, 1, 3, 4, 0, 2, 1, 3, 0,
76 4, 1, 2, 0, 3, 1, 4, 2, 5, 0, 3, 1, 2, 0, 4, 5, 3, 1, 0, 2, 4, 5, 6, 1, 0, 3, 2, 4, 1, 0, 5, 3, 6,
77 2, 4, 0, 1, 5, 3, 2, 6, 7, 0, 1, 4, 3, 2, 5, 0, 6, 1, 7, 4, 2, 3, 0, 5, 1, 6, 4, 7, 8, 2, 0, 3};
79 for (
size_t i = 0; i < ncoeff; i++) {
84 m_xnl.emplace_back(coeff);
93 for (std::vector<xnlc>::const_iterator it =
m_xnl.begin(); it !=
m_xnl.end(); ++it) {
95 auto l =
static_cast<double>(it->l);
96 m_alpha.emplace_back((2.0 * l + 1) * 6.0 *
x *
x / (
x *
x - l * (l + 1)));
106 for (
auto &coeff :
m_xnl) {
109 auto l =
static_cast<unsigned int>(coeff.l);
111 double J0 = (Qa * boost::math::sph_bessel(l + 1, Qa) - l * boost::math::sph_bessel(l, Qa)) / (Qa * Qa -
x *
x);
113 double J1 = (Qa * boost::math::sph_bessel(l + 1, Qa) - l * boost::math::sph_bessel(l, Qa)) / (Qa * Qa -
x *
x);
137 std::vector<double> jl(2 +
m_lmax);
138 for (
size_t l = 0; l < 2 +
m_lmax; l++) {
139 jl[l] = boost::math::sph_bessel(
static_cast<unsigned int>(l), a);
143 size_t ncoeff =
m_xnl.size();
144 std::vector<double> YJ(ncoeff);
146 for (
size_t i = 0; i < ncoeff; i++) {
148 auto l =
static_cast<unsigned int>(
m_xnl[i].l);
152 J = (a * jl[l + 1] - l * jl[l]) / (a * a -
x *
x);
179 throw std::runtime_error(
"No Q attribute provided and cannot retrieve from worksapce.");
185 g_log.
debug() <<
"Get Q value for workspace index " << specIdx <<
": " << Q <<
'\n';
189 g_log.
debug() <<
"Using Q attribute: " << Q <<
'\n';
193 if (I < std::numeric_limits<double>::epsilon() || R < std::numeric_limits<double>::epsilon() ||
194 D < std::numeric_limits<double>::epsilon()) {
195 for (
size_t i = 0; i < nData; i++) {
196 out[i] = std::numeric_limits<double>::infinity();
202 std::vector<double> HWHM;
203 size_t ncoeff =
m_xnl.size();
204 for (
size_t n = 0;
n < ncoeff;
n++) {
206 HWHM.emplace_back(
m_hbar *
x *
x * D / (R * R));
209 std::vector<double> YJ;
211 for (
size_t i = 0; i < nData; i++) {
212 double energy = xValues[i] - S;
214 for (
size_t n = 0;
n < ncoeff;
n++) {
215 double L = (1.0 / M_PI) * HWHM[
n] / (HWHM[
n] * HWHM[
n] +
energy *
energy);
216 out[i] += I * YJ[
n] * L;
232 auto workspace = std::dynamic_pointer_cast<const API::MatrixWorkspace>(ws);
236 const auto &spectrumInfo =
workspace->spectrumInfo();
237 const auto &detectorIDs =
workspace->detectorInfo().detectorIDs();
238 for (
size_t idx = 0; idx < spectrumInfo.size(); idx++) {
239 if (!spectrumInfo.hasDetectors(idx)) {
241 g_log.
information(
"Cannot populate Q values from workspace - no detectors set.");
245 const auto detectorIndex = spectrumInfo.spectrumDefinition(idx)[0].first;
249 double usingTheta = 0.5 * spectrumInfo.twoTheta(idx);
254 }
catch (std::runtime_error &) {
257 "find EFixed value.");
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
IPeaksWorkspace_sptr workspace
static Kernel::Logger g_log
Logger instance.
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
double getParameter(size_t i) const override
Get i-th parameter.
Inelastic part of the DiffSphere function.
void initXnlCoeff()
initialize the Xnl coefficients
size_t m_lmax
maximum value of l in xnlist
void function1D(double *out, const double *xValues, const size_t nData) const override
Calculate function values on an energy domain.
double m_divZone
linear interpolation zone around the numerical divergence of factor J
std::vector< double > LorentzianCoefficients(double a) const
Calculate the (2l+1)*A_{n,l} coefficients for each Lorentzian.
std::vector< xnlc > m_xnl
xnl coefficients
double m_hbar
Plank's constant divided by , in units of meV*THz.
void initLinJlist()
initialize the list of parameters for A_{n,l} linear interpolation around the indeterminacy point
void initAlphaCoeff()
initialize the m_alpha coefficients
std::vector< double > m_alpha
certain coefficients invariant during fitting
void setWorkspace(std::shared_ptr< const API::Workspace > ws) override
Cache Q values from the workspace.
void init() override
overwrite IFunction base class methods
std::vector< linearJ > m_linearJlist
list of linearized J values
std::vector< double > m_qValueCache
list of calculated Q values
The Logger class is in charge of the publishing messages from the framework through various channels.
void debug(const std::string &msg)
Logs at debug level.
void information(const std::string &msg)
Logs at information level.
static double convertToElasticQ(const double theta, const double efixed)
Convert to ElasticQ from Energy.
Kernel::Logger g_log("ExperimentInfo")
static logger object
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
simple structure to hold a linear interpolation of factor J around its numerical divergence point
structure to hold info on Volino's coefficients