15using namespace CurveFitting;
17using namespace Kernel;
24std::string isPositiveAndMultipleOf05(
double value) {
25 double temp =
value * 2;
27 return "Spin value should be greater than zero";
29 if (floor(temp) != ceil(temp)) {
30 return "Spin value should be a multiple of 0.5";
35double getSinSquared(
const double &cosSquared) {
return 1 - cosSquared; }
37double getCosSquared(
const double &cos2squared) {
return 0.5 * (1 + std::sqrt(cos2squared)); }
42 declareParameter(
"FreqD", 0.01,
"Angular Frequency due to dipolar coupling (MHz)");
44 "Angular Frequency due to quadrupole interaction of the nuclear spin (MHz) due to a field gradient"
45 "exerted by the presence of the muon");
57 const double J2 = round(2 * J);
61 std::valarray<double> xValArray(xValues, nData);
63 const std::valarray<double> gau = std::exp(-0.5 * pow((Sigma * xValArray), 2));
64 const std::valarray<double> Lor = std::exp(-Lambda * xValArray);
66 std::valarray<double> positiveLambda;
67 std::valarray<double> negativeLambda;
68 std::valarray<double> cos2AlphaSquared;
72 std::valarray<double> Px;
73 calculatePx(Px, xValArray, cos2AlphaSquared, negativeLambda, positiveLambda, J2);
75 std::valarray<double> Pz;
76 calculatePz(Pz, xValArray, cos2AlphaSquared, negativeLambda, positiveLambda, J2);
78 const std::valarray<double> outValArray = A0 * gau * Lor * (1. / 3.) * (2 * Px + Pz);
79 std::copy(begin(outValArray), end(outValArray), out);
91 std::valarray<double> &positiveLambda,
const double &J2)
const {
94 const double J = J2 / 2;
96 const double OmegaD = 2 * M_PI * FreqD;
97 const double OmegaQ = 2 * M_PI * FreqQ;
99 const size_t size = int(J2 + 2);
100 cos2AlphaSquared.resize(size);
101 negativeLambda.resize(size);
102 positiveLambda.resize(size);
105 double q1 =
getQ1(
m, OmegaQ, OmegaD);
106 double q2 =
getQ2(
m, J, OmegaD);
107 double q3 =
getQ3(
m, OmegaQ, OmegaD);
108 double qq =
getQQ(q1, q2);
109 double Wm = std::sqrt(qq);
115 for (
size_t i = 1; i < size - 1; i++) {
116 m =
static_cast<double>(i) - J;
117 q1 =
getQ1(
m, OmegaQ, OmegaD);
119 q3 =
getQ3(
m, OmegaQ, OmegaD);
128 m =
static_cast<double>(size) - 1 - J;
129 q1 =
getQ1(
m, OmegaQ, OmegaD);
131 q3 =
getQ3(
m, OmegaQ, OmegaD);
148double Meier::getQ1(
const double &
m,
const double &OmegaQ,
const double &OmegaD)
const {
149 return (OmegaQ + OmegaD) * (2 *
m - 1);
160double Meier::getQ2(
const double &
m,
const double &J,
const double &OmegaD)
const {
161 return OmegaD * std::sqrt(J * (J + 1) -
m * (
m - 1));
172double Meier::getQ3(
const double &
m,
const double &OmegaQ,
const double &OmegaD)
const {
173 return OmegaQ * (2 * pow(
m, 2) - 2 *
m + 1) + OmegaD;
183double Meier::getQQ(
const double &q1,
const double &q2)
const {
return pow(q1, 2) + pow(q2, 2); }
213 return OmegaQ * pow(J, 2) - OmegaD * J;
235 const std::valarray<double> &cos2AlphaSquared,
const std::valarray<double> &negativeLambda,
236 const std::valarray<double> &positiveLambda,
const double &J2)
const {
237 std::valarray<double> tx(xValues.size());
238 for (
int i = 0; i < int(J2) + 1; i++) {
239 const double cosAlphaSquared = getCosSquared(cos2AlphaSquared[i]);
240 const double sinAlphaSquared = getSinSquared(cosAlphaSquared);
242 const double cosAlphaSquared2 = getCosSquared(cos2AlphaSquared[i + 1]);
243 const double sinAlphaSquared2 = getSinSquared(cosAlphaSquared2);
245 const std::valarray<double> a =
246 cosAlphaSquared2 * sinAlphaSquared * std::cos((positiveLambda[i + 1] - positiveLambda[i]) * xValues);
247 const std::valarray<double> b =
248 cosAlphaSquared2 * cosAlphaSquared * std::cos((positiveLambda[i + 1] - negativeLambda[i]) * xValues);
249 const std::valarray<double> c =
250 sinAlphaSquared2 * sinAlphaSquared * std::cos((negativeLambda[i + 1] - positiveLambda[i]) * xValues);
251 const std::valarray<double>
d =
252 sinAlphaSquared2 * cosAlphaSquared * std::cos((negativeLambda[i + 1] - negativeLambda[i]) * xValues);
255 const double J = J2 / 2;
256 Px = tx / (2 * J + 1);
269 const std::valarray<double> &cos2AlphaSquared,
const std::valarray<double> &negativeLambda,
270 const std::valarray<double> &positiveLambda,
const double &J2)
const {
271 std::valarray<double> tz(xValues.size());
272 for (
size_t i = 1; i < (size_t)J2 + 1; i++) {
273 const double sin2AlphaSquared = getSinSquared(cos2AlphaSquared[i]);
274 tz += cos2AlphaSquared[i] + sin2AlphaSquared * std::cos((positiveLambda[i] - negativeLambda[i]) * xValues);
276 const double J = J2 / 2;
277 Pz = (1 + tz) / (2 * J + 1);
double value
The value of the point.
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Attribute is a non-fitting parameter.
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.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
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.
void init() override
Function initialization. Declare function parameters in this method.
double getCos2AlphaSquared(const double &q1, const double &qq) const
Calculates and returns the value of cos 2*alpha sequared at a given index i This function is used by ...
void calculatePz(std::valarray< double > &Pz, const std::valarray< double > &xValues, const std::valarray< double > &cos2AlphaSquared, const std::valarray< double > &negativeLambda, const std::valarray< double > &positiveLambda, const double &J2) const
Calculates the polarization in the z direction.
double getQ1(const double &m, const double &OmegaQ, const double &OmegaD) const
Calculates and returns the value of q1 This function is used by precomputeIntermediateSteps to calcul...
double getQ3(const double &J, const double &OmegaQ, const double &OmegaD) const
Calculates and returns the value of q2 This function is used by precomputeIntermediateSteps to calcul...
double getNegativeLambda(const double &q3, const double &Wm) const
Calculates and returns the value of negative lambda This function is used by precomputeIntermediateSt...
void function1D(double *out, const double *xValues, const size_t nData) const override
Function you want to fit to.
void calculatePx(std::valarray< double > &Px, const std::valarray< double > &xValues, const std::valarray< double > &cos2AlphaSquared, const std::valarray< double > &negativeLambda, const std::valarray< double > &positiveLambda, const double &J2) const
Calculates the polarization in the x direction.
void precomputeIntermediateSteps(std::valarray< double > &cos2AlphaSquared, std::valarray< double > &negativeLambda, std::valarray< double > &positiveLambda, const double &J2) const
Precomputes intermediate terms used to calculate the polrization in the x and z directions.
double getPositiveLambda(const double &q3, const double &Wm) const
Calculates and returns the value of positive lambda This function is used by precomputeIntermediateSt...
double getQ2(const double &m, const double &J, const double &OmegaD) const
Calculates and returns the value of q2 This function is used by precomputeIntermediateSteps to calcul...
double getBaseLambda(const double &OmegaQ, const double &OmegaD, const double &J) const
Calculates and returns the value of lambda for the special cases i.e it is the value of the first ele...
double getQQ(const double &q1, const double &q2) const
Calculates and returns the value of qq This function is used by precomputeIntermediateSteps to calcul...
LambdaValidator provides a quick way to create custom validation objects using a validator function o...