Mantid
Loading...
Searching...
No Matches
MultivariateGaussianComptonProfile.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//------------------------------------------------------------------------------------------------
8// Includes
9//------------------------------------------------------------------------------------------------
12
13#include <cmath>
14
16
17using namespace CurveFitting;
18DECLARE_FUNCTION(MultivariateGaussianComptonProfile)
19
20const char *MultivariateGaussianComptonProfile::AMP_PARAM = "Intensity";
24const char *MultivariateGaussianComptonProfile::STEPS_ATTR = "IntegrationSteps";
25
27 : ComptonProfile(), m_integrationSteps(256), m_thetaStep(0.0), m_phiStep(0.0) {}
28
32std::string MultivariateGaussianComptonProfile::name() const { return "MultivariateGaussianComptonProfile"; }
33
36 declareParameter(AMP_PARAM, 1.0, "Gaussian intensity parameter");
37 declareParameter(SIGMA_X_PARAM, 1.0, "Sigma X parameter");
38 declareParameter(SIGMA_Y_PARAM, 1.0, "Sigma Y parameter");
39 declareParameter(SIGMA_Z_PARAM, 1.0, "Sigma Z parameter");
40}
41
45}
46
53 if (name == STEPS_ATTR) {
54 int steps = value.asInt();
55
56 if (steps < 1)
57 throw std::runtime_error(std::string(STEPS_ATTR) + " attribute must be positive and non-zero");
58
59 if (steps % 2 == 1)
60 throw std::runtime_error(std::string(STEPS_ATTR) + " attribute must be an even number");
61
62 m_integrationSteps = steps;
63 m_thetaStep = M_PI / steps;
64 m_phiStep = (M_PI / 2.0) / steps;
65 }
66}
67
69 return std::vector<size_t>(1, this->parameterIndex(AMP_PARAM));
70}
71
82 const HistogramData::HistogramE &errors) const {
83 std::vector<double> result(ySpace().size());
84 this->massProfile(result.data(), ySpace().size());
85 std::transform(result.begin(), result.end(), errors.begin(), result.begin(), std::divides<double>());
86 cmatrix.setColumn(start, result);
87 return 1;
88}
89
95void MultivariateGaussianComptonProfile::massProfile(double *result, const size_t nData) const {
96 const double amplitude(getParameter(AMP_PARAM));
97 this->massProfile(result, nData, amplitude);
98}
99
100void MultivariateGaussianComptonProfile::massProfile(double *result, const size_t nData, const double amplitude) const {
101 std::vector<double> s2Cache;
102 buildS2Cache(s2Cache);
103
104 const double sigmaX(getParameter(SIGMA_X_PARAM));
105 const double sigmaY(getParameter(SIGMA_Y_PARAM));
106 const double sigmaZ(getParameter(SIGMA_Z_PARAM));
107
108 const double prefactorJ = (1.0 / (sqrt(2.0 * M_PI) * sigmaX * sigmaY * sigmaZ)) * (2.0 / M_PI);
109 const double prefactorFSE =
110 (pow(sigmaX, 4) + pow(sigmaY, 4) + pow(sigmaZ, 4)) / (9.0 * sqrt(2.0 * M_PI) * sigmaX * sigmaY * sigmaZ);
111
112 const auto &yspace = ySpace();
113 const auto &modq = modQ();
114 if (modq.empty() || yspace.empty()) {
115 throw std::runtime_error("Y values or Q values not set");
116 }
117
118 for (size_t i = 0; i < nData; i++) {
119 const double y(yspace[i]);
120 const double q(modq[i]);
121
122 double j = prefactorJ * calculateJ(s2Cache, y);
123 double fse = (prefactorFSE / q) * calculateFSE(s2Cache, y);
124
125 result[i] = amplitude * (j + fse);
126 }
127}
128
135double MultivariateGaussianComptonProfile::calculateJ(std::vector<double> s2Cache, double y) const {
136 double sum(0.0);
137
138 for (int i = 0; i < m_integrationSteps; i++) {
139 for (int j = 0; j < m_integrationSteps; j++) {
140 double s2 = s2Cache[i * m_integrationSteps + j];
141 sum += intervalCoeff(i, j) * calculateIntegrandJ(s2, y);
142 }
143 }
144
145 double fact = (m_thetaStep * m_phiStep) / 9.0;
146
147 return fact * sum;
148}
149
156double MultivariateGaussianComptonProfile::calculateFSE(std::vector<double> s2Cache, double y) const {
157 double sum(0.0);
158
159 for (int i = 0; i < m_integrationSteps; i++) {
160 for (int j = 0; j < m_integrationSteps; j++) {
161 double s2 = s2Cache[i * m_integrationSteps + j];
162 sum += intervalCoeff(i, j) * calculateIntegrandFSE(s2, y);
163 }
164 }
165
166 double fact = (m_thetaStep * m_phiStep) / 9.0;
167
168 return fact * sum;
169}
170
185 double a = 1.0;
186 double b = 1.0;
187
188 if (i > 0 && i <= m_integrationSteps)
189 a = i % 2 == 1 ? 4 : 2;
190
191 if (j > 0 && j <= m_integrationSteps)
192 b = j % 2 == 1 ? 4 : 2;
193
194 return a * b;
195}
196
201void MultivariateGaussianComptonProfile::buildS2Cache(std::vector<double> &s2Cache) const {
202 s2Cache.clear();
203
204 double sigmaX2(getParameter(SIGMA_X_PARAM));
205 double sigmaY2(getParameter(SIGMA_Y_PARAM));
206 double sigmaZ2(getParameter(SIGMA_Z_PARAM));
207
208 sigmaX2 *= sigmaX2;
209 sigmaY2 *= sigmaY2;
210 sigmaZ2 *= sigmaZ2;
211
212 for (int i = 0; i <= m_integrationSteps; i++) {
213 const double theta = m_thetaStep * i;
214 for (int j = 0; j <= m_integrationSteps; j++) {
215 const double phi = m_phiStep * j;
216
217 double sinTheta2 = pow(sin(theta), 2);
218 double sinPhi2 = pow(sin(phi), 2);
219 double cosTheta2 = pow(cos(theta), 2);
220 double cosPhi2 = pow(cos(phi), 2);
221
222 double x = (sinTheta2 * cosPhi2) / sigmaX2;
223 double y = (sinTheta2 * sinPhi2) / sigmaY2;
224 double z = cosTheta2 / sigmaZ2;
225
226 double s2 = x + y + z;
227
228 s2 = 1.0 / s2;
229
230 s2Cache.emplace_back(s2);
231 }
232 }
233}
234
235} // namespace Mantid::CurveFitting::Functions
double value
The value of the point.
Definition: FitMW.cpp:51
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
Definition: IFunction.cpp:1418
virtual void declareAttributes()
Override to declare function attributes.
Definition: IFunction.h:676
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Definition: IFunction.cpp:1409
size_t parameterIndex(const std::string &name) const override
Returns the index of parameter name.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
double getParameter(size_t i) const override
Get i-th parameter.
This class serves as a base-class for ComptonProfile type functions.
const std::vector< double > & modQ() const
Access Q values cache.
void declareParameters() override
Declare parameters that will never participate in the fit.
const std::vector< double > & ySpace() const
Access y-values cache.
std::string name() const override
A string identifier for this function.
double calculateFSE(std::vector< double > s2Cache, double y) const
Calculates the A3 FSE correction.
double calculateIntegrandFSE(double s2, double y) const
Calculates the integrand of the A3 FSE correction.
void setAttribute(const std::string &name, const Attribute &value) override
Set an attribute value (and possibly cache its value)
void massProfile(double *result, const size_t nData) const override
Compute the function.
double calculateIntegrandJ(double s2, double y) const
Calculates the integrand of the mass profile.
double intervalCoeff(int i, int j) const
Obtains a cell of the coefficient grid for Simpson's integration in 2D.
std::vector< size_t > intensityParameterIndices() const override
Returns the indices of the intensity parameters.
size_t fillConstraintMatrix(Kernel::DblMatrix &cmatrix, const size_t start, const HistogramData::HistogramE &errors) const override
Fill in the columns of the matrix for this mass.
void declareAttributes() override
Declare parameters that will never participate in the fit.
void buildS2Cache(std::vector< double > &s2Cache) const
Caches values of S2 for all theta and phi in integration range.
double calculateJ(std::vector< double > s2Cache, double y) const
Calculates the mass profile.
void setColumn(const size_t nCol, const std::vector< T > &newCol)
Definition: Matrix.cpp:675