Mantid
Loading...
Searching...
No Matches
PDFFourierTransform2.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 +
8#include "MantidAPI/Axis.h"
9#include "MantidAPI/Run.h"
10#include "MantidAPI/Sample.h"
14#include "MantidHistogramData/Histogram.h"
15#include "MantidHistogramData/LinearGenerator.h"
22#include "MantidKernel/Unit.h"
24
25#include <cmath>
26#include <sstream>
27
28namespace Mantid::Algorithms {
29
30using std::string;
31using namespace HistogramData;
32
33// Register the algorithm into the AlgorithmFactory
34DECLARE_ALGORITHM(PDFFourierTransform2)
35
36using namespace Mantid::Kernel;
37using namespace Mantid::API;
38using namespace DataObjects;
39
40namespace { // anonymous namespace
42const string BIG_G_OF_R("G(r)");
44const string LITTLE_G_OF_R("g(r)");
46const string RDF_OF_R("RDF(r)");
48const string G_K_OF_R("G_k(r)");
49
51const string S_OF_Q("S(Q)");
53const string S_OF_Q_MINUS_ONE("S(Q)-1");
55const string Q_S_OF_Q_MINUS_ONE("Q[S(Q)-1]");
56
57const string FORWARD("Forward");
58
59const string BACKWARD("Backward");
60
61} // namespace
62
63const std::string PDFFourierTransform2::name() const { return "PDFFourierTransform"; }
64
65int PDFFourierTransform2::version() const { return 2; }
66
67const std::string PDFFourierTransform2::category() const { return "Diffraction\\Utility"; }
68
72 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
73 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input),
74 "Input spectrum density or paired-distribution function");
75 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
76 "Result paired-distribution function or Input spectrum density");
77
78 std::vector<std::string> directionOptions;
79 directionOptions.emplace_back(FORWARD);
80 directionOptions.emplace_back(BACKWARD);
81 declareProperty("Direction", FORWARD, std::make_shared<StringListValidator>(directionOptions),
82 "The direction of the fourier transform");
83 declareProperty("rho0", EMPTY_DBL(), mustBePositive,
84 "Average number density used for g(r) and RDF(r) conversions (optional)");
85 declareProperty("Filter", false, "Set to apply Lorch function filter to the input");
86
87 // Set up spectral density data type
88 std::vector<std::string> soqTypes;
89 soqTypes.emplace_back(S_OF_Q);
90 soqTypes.emplace_back(S_OF_Q_MINUS_ONE);
91 soqTypes.emplace_back(Q_S_OF_Q_MINUS_ONE);
92 declareProperty("InputSofQType", S_OF_Q, std::make_shared<StringListValidator>(soqTypes),
93 "To identify spectral density function (deprecated)");
94 setPropertySettings("InputSofQType", std::make_unique<InvisibleProperty>());
95 declareProperty("SofQType", S_OF_Q, std::make_shared<StringListValidator>(soqTypes),
96 "To identify spectral density function");
97 mustBePositive->setLower(0.0);
98
99 declareProperty("DeltaQ", EMPTY_DBL(), mustBePositive,
100 "Step size of Q of S(Q) to calculate. Default = "
101 ":math:`\\frac{\\pi}{R_{max}}`.");
102 setPropertySettings("DeltaQ", std::make_unique<EnabledWhenProperty>("Direction", IS_EQUAL_TO, BACKWARD));
103 declareProperty("Qmin", EMPTY_DBL(), mustBePositive,
104 "Minimum Q in S(Q) to calculate in Fourier transform (optional).");
105 declareProperty("Qmax", EMPTY_DBL(), mustBePositive,
106 "Maximum Q in S(Q) to calculate in Fourier transform. "
107 "(optional, defaults to 40 on backward transform.)");
108
109 // Set up PDF data type
110 std::vector<std::string> pdfTypes;
111 pdfTypes.emplace_back(BIG_G_OF_R);
112 pdfTypes.emplace_back(LITTLE_G_OF_R);
113 pdfTypes.emplace_back(RDF_OF_R);
114 pdfTypes.emplace_back(G_K_OF_R);
115 declareProperty("PDFType", BIG_G_OF_R, std::make_shared<StringListValidator>(pdfTypes),
116 "Type of output PDF including G(r)");
117
118 declareProperty("DeltaR", EMPTY_DBL(), mustBePositive,
119 "Step size of r of G(r) to calculate. Default = "
120 ":math:`\\frac{\\pi}{Q_{max}}`.");
121 setPropertySettings("DeltaR", std::make_unique<EnabledWhenProperty>("Direction", IS_EQUAL_TO, FORWARD));
122 declareProperty("Rmin", EMPTY_DBL(), mustBePositive, "Minimum r for G(r) to calculate. (optional)");
123 declareProperty("Rmax", EMPTY_DBL(), mustBePositive,
124 "Maximum r for G(r) to calculate. (optional, defaults to 20 "
125 "on forward transform.)");
126
127 string recipGroup("Reciprocal Space");
128 setPropertyGroup("SofQType", recipGroup);
129 setPropertyGroup("DeltaQ", recipGroup);
130 setPropertyGroup("Qmin", recipGroup);
131 setPropertyGroup("Qmax", recipGroup);
132
133 string realGroup("Real Space");
134 setPropertyGroup("PDFType", realGroup);
135 setPropertyGroup("DeltaR", realGroup);
136 setPropertyGroup("Rmin", realGroup);
137 setPropertyGroup("Rmax", realGroup);
138}
139
140std::map<string, string> PDFFourierTransform2::validateInputs() {
141 std::map<string, string> result;
142
143 double Qmin = getProperty("Qmin");
144 double Qmax = getProperty("Qmax");
145 if ((!isEmpty(Qmin)) && (!isEmpty(Qmax)))
146 if (Qmax <= Qmin)
147 result["Qmax"] = "Must be greater than Qmin";
148
149 // check for null pointers - this is to protect against workspace groups
150 API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
151 if (!inputWS) {
152 return result;
153 }
154
155 if (inputWS->getNumberHistograms() != 1) {
156 result["InputWorkspace"] = "Input workspace must have only one spectrum";
157 }
158 const std::string inputXunit = inputWS->getAxis(0)->unit()->unitID();
159 if (inputXunit != "MomentumTransfer" && inputXunit != "dSpacing" && inputXunit != "AtomicDistance") {
160 result["InputWorkspace"] = "Input workspace units not supported";
161 }
162
163 return result;
164}
165
166size_t PDFFourierTransform2::determineMinIndex(double min, const std::vector<double> &X, const std::vector<double> &Y) {
167 // check against available X-range
168 if (isEmpty(min)) {
169 min = X.front();
170 } else if (min < X.front()) {
171 g_log.information("Specified input min < range of data. Adjusting to data range.");
172 min = X.front();
173 }
174
175 // get index for the min from the X-range, tightening the range if a partial x bin value is provided
176 auto iter = std::lower_bound(X.begin(), X.end(), min);
177 size_t min_index = std::distance(X.begin(), iter);
178
179 // go to first non-nan value
180 auto iter_first_normal =
181 std::find_if(std::next(Y.begin(), min_index), Y.end(), static_cast<bool (*)(double)>(std::isnormal));
182 size_t first_normal_index = std::distance(Y.begin(), iter_first_normal);
183 if (first_normal_index > min_index) {
184 g_log.information("Specified input min where data is nan/inf or zero. Adjusting to data range.");
185 min_index = first_normal_index;
186 }
187
188 return min_index;
189}
190
191size_t PDFFourierTransform2::determineMaxIndex(double max, const std::vector<double> &X, const std::vector<double> &Y) {
192 // check against available X-range
193 if (isEmpty(max)) {
194 max = X.back();
195 } else if (max > X.back()) {
196 g_log.information() << "Specified input max > range of data. Adjusting to data range.\n";
197 max = X.back();
198 }
199
200 // get index for the max from the X-range, tightening the range if a partial x bin value is provided
201 auto iter = std::upper_bound(X.begin(), X.end(), max) - 1;
202 size_t max_index = std::distance(X.begin(), iter);
203
204 // go to first non-nan value. This works for both histogram (bin edge) data and
205 // point data, as the integration proceeds by calculating rectangles between pairs of X values.
206 // For point data the Y value corresponding to the left of this pair is used in the nested for loop in the exec.
207 auto back_iter = std::find_if(Y.rbegin(), Y.rend(), static_cast<bool (*)(double)>(std::isnormal));
208 size_t first_normal_index = Y.size() - std::distance(Y.rbegin(), back_iter);
209 if (first_normal_index < max_index) {
210 g_log.information("Specified input max where data is nan/inf or zero. Adjusting to data range.");
211 max_index = first_normal_index;
212 }
213
214 return max_index;
215}
216
218 double rho0 = getProperty("rho0");
219
220 if (isEmpty(rho0)) {
221 API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
222
223 const Kernel::Material &material = inputWS->sample().getMaterial();
224 double materialDensity = material.numberDensity();
225
226 if (!isEmpty(materialDensity) && materialDensity > 0)
227 rho0 = materialDensity;
228 else
229 rho0 = 1.;
230 }
231
232 return rho0;
233}
234
235void PDFFourierTransform2::convertToSQMinus1(std::vector<double> &FOfQ, std::vector<double> &Q,
236 std::vector<double> &DFOfQ, const std::vector<double> &DQ) {
237 // convert to S(Q)-1
238 string soqType = getProperty("SofQType");
239 string inputSOQType = getProperty("InputSofQType");
240 if (!isDefault("InputSofQType") && isDefault("SofQType")) {
241 soqType = inputSOQType;
242 g_log.warning() << "InputSofQType has been deprecated and replaced by SofQType\n";
243 }
244 if (soqType == S_OF_Q) {
245 g_log.information() << "Subtracting one from all values\n";
246 // there is no error propagation for subtracting one
247 std::for_each(FOfQ.begin(), FOfQ.end(), [](double &F) { F--; });
248 soqType = S_OF_Q_MINUS_ONE;
249 }
250 if (soqType == Q_S_OF_Q_MINUS_ONE) {
251 g_log.information() << "Dividing all values by Q\n";
252 // error propagation
253 for (size_t i = 0; i < DFOfQ.size(); ++i) {
254 DFOfQ[i] = (Q[i] / DQ[i] + FOfQ[i] / DFOfQ[i]) * (FOfQ[i] / Q[i]);
255 }
256 // convert the function
257 std::transform(FOfQ.begin(), FOfQ.end(), FOfQ.begin(), Q.begin(), std::divides<double>());
258 soqType = S_OF_Q_MINUS_ONE;
259 }
260 if (soqType != S_OF_Q_MINUS_ONE) {
261 // should never get here
262 std::stringstream msg;
263 msg << "Do not understand SofQType = " << soqType;
264 throw std::runtime_error(msg.str());
265 }
266 return;
267}
268
269void PDFFourierTransform2::convertToLittleGRMinus1(std::vector<double> &FOfR, const std::vector<double> &R,
270 std::vector<double> &DFOfR, const std::vector<double> &DR,
271 const std::string &PDFType, const double &rho0,
272 const double &cohScatLen) {
273 if (PDFType == LITTLE_G_OF_R) {
274 for (size_t i = 0; i < FOfR.size(); ++i) {
275 // transform the data
276 FOfR[i] = FOfR[i] - 1.0;
277 }
278 } else if (PDFType == BIG_G_OF_R) {
279 const double factor = 4. * M_PI * rho0;
280 for (size_t i = 0; i < FOfR.size(); ++i) {
281 // error propagation - assuming uncertainty in r = 0
282 DFOfR[i] = (R[i] / DR[i] + FOfR[i] / DFOfR[i]) * (FOfR[i] / R[i]);
283 // transform the data
284 FOfR[i] = FOfR[i] / (factor * R[i]);
285 }
286 } else if (PDFType == RDF_OF_R) {
287 const double factor = 4. * M_PI * rho0;
288 for (size_t i = 0; i < FOfR.size(); ++i) {
289 // error propagation - assuming uncertainty in r = 0
290 DFOfR[i] = (2.0 * R[i] / DR[i] + FOfR[i] / DFOfR[i]) * (FOfR[i] / R[i]);
291 // transform the data
292 FOfR[i] = FOfR[i] / (factor * R[i] * R[i]) - 1.0;
293 }
294 } else if (PDFType == G_K_OF_R) {
295 const double factor = 0.01 * pow(cohScatLen, 2);
296
297 for (size_t i = 0; i < FOfR.size(); ++i) {
298 // error propagation - assuming uncertainty in r = 0
299 DFOfR[i] = DFOfR[i] / factor;
300 // transform the data
301 FOfR[i] = FOfR[i] / factor;
302 }
303 }
304 return;
305}
306
307void PDFFourierTransform2::convertFromSQMinus1(HistogramData::HistogramY &FOfQ, const HistogramData::HistogramX &Q,
308 HistogramData::HistogramE &DFOfQ) {
309 // convert to S(Q)-1string
310 string soqType = getProperty("SofQType");
311 string inputSOQType = getProperty("InputSofQType");
312 if (!isDefault("InputSofQType") && isDefault("SofQType")) {
313 soqType = inputSOQType;
314 g_log.warning() << "InputSofQType has been deprecated and replaced by SofQType\n";
315 }
316 if (soqType == S_OF_Q) {
317 for (size_t i = 0; i < FOfQ.size(); ++i) {
318 // transform the data
319 FOfQ[i] = FOfQ[i] + 1.0;
320 }
321 } else if (soqType == Q_S_OF_Q_MINUS_ONE) {
322 for (size_t i = 0; i < FOfQ.size(); ++i) {
323 DFOfQ[i] = Q[i] * DFOfQ[i];
324 FOfQ[i] = FOfQ[i] * Q[i];
325 }
326 }
327 return;
328}
329
330void PDFFourierTransform2::convertFromLittleGRMinus1(HistogramData::HistogramY &FOfR,
331 const HistogramData::HistogramX &R,
332 HistogramData::HistogramE &DFOfR, const std::string &PDFType,
333 const double &rho0, const double &cohScatLen) {
334 // convert to the correct form of PDF
335 if (PDFType == LITTLE_G_OF_R) {
336 for (size_t i = 0; i < FOfR.size(); ++i) {
337 // transform the data
338 FOfR[i] = FOfR[i] + 1.0;
339 }
340 } else if (PDFType == BIG_G_OF_R) {
341 const double factor = 4. * M_PI * rho0;
342 for (size_t i = 0; i < FOfR.size(); ++i) {
343 // error propagation - assuming uncertainty in r = 0
344 DFOfR[i] = DFOfR[i] * R[i];
345 // transform the data
346 FOfR[i] = FOfR[i] * factor * R[i];
347 }
348 } else if (PDFType == RDF_OF_R) {
349 const double factor = 4. * M_PI * rho0;
350 for (size_t i = 0; i < FOfR.size(); ++i) {
351 // error propagation - assuming uncertainty in r = 0
352 DFOfR[i] = DFOfR[i] * R[i];
353 // transform the data
354 FOfR[i] = (FOfR[i] + 1.0) * factor * R[i] * R[i];
355 }
356 } else if (PDFType == G_K_OF_R) {
357 const double factor = 0.01 * pow(cohScatLen, 2);
358
359 for (size_t i = 0; i < FOfR.size(); ++i) {
360 // error propagation - assuming uncertainty in r = 0
361 DFOfR[i] = DFOfR[i] * factor;
362 // transform the data
363 FOfR[i] = FOfR[i] * factor;
364 }
365 }
366 return;
367}
368//----------------------------------------------------------------------------------------------
372 // get input data
373 API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
374 auto inputX = inputWS->x(0).rawData(); // x for input
375 std::vector<double> inputDX(inputX.size(), 0.0); // dx for input
376 if (inputWS->sharedDx(0))
377 inputDX = inputWS->dx(0).rawData();
378 auto inputY = inputWS->y(0).rawData(); // y for input
379 auto inputDY = inputWS->e(0).rawData(); // dy for input
380
381 // need bin edges
382 if (inputX.size() == inputY.size()) {
383 inputX = BinEdges(Points(inputWS->x(0))).rawData();
384 }
385
386 // transform input data into Q/MomentumTransfer
387 string direction = getProperty("Direction");
388 const std::string inputXunit = inputWS->getAxis(0)->unit()->unitID();
389 if (inputXunit == "MomentumTransfer") {
390 // nothing to do
391 } else if (inputXunit == "dSpacing") {
392 // convert the x-units to Q/MomentumTransfer
393 const double PI_2(2. * M_PI);
394 std::for_each(inputX.begin(), inputX.end(), [&PI_2](double &Q) { Q /= PI_2; });
395 std::transform(inputDX.begin(), inputDX.end(), inputX.begin(), inputDX.begin(), std::divides<double>());
396 // reverse all of the arrays
397 std::reverse(inputX.begin(), inputX.end());
398 std::reverse(inputDX.begin(), inputDX.end());
399 std::reverse(inputY.begin(), inputY.end());
400 std::reverse(inputDY.begin(), inputDY.end());
401 } else if (inputXunit == "AtomicDistance") {
402 // nothing to do
403 }
404 g_log.debug() << "Input unit is " << inputXunit << "\n";
405
406 // convert from histogram to density
407 if (!inputWS->isHistogramData()) {
408 g_log.warning() << "This algorithm has not been tested on density data "
409 "(only on histograms)\n";
410 /* Don't do anything for now
411 double deltaQ;
412 for (size_t i = 0; i < inputFOfQ.size(); ++i)
413 {
414 deltaQ = inputQ[i+1] -inputQ[i];
415 inputFOfQ[i] = inputFOfQ[i]*deltaQ;
416 inputDfOfQ[i] = inputDfOfQ[i]*deltaQ; // TODO feels wrong
417 inputQ[i] += -.5*deltaQ;
418 inputDQ[i] += .5*(inputDQ[i] + inputDQ[i+1]); // TODO running average
419 }
420 inputQ.emplace_back(inputQ.back()+deltaQ);
421 inputDQ.emplace_back(inputDQ.back()); // copy last value
422 */
423 }
424
425 const std::string PDFType = getProperty("PDFType");
426 double rho0 = determineRho0();
427 const Kernel::Material &material = inputWS->sample().getMaterial();
428 const auto cohScatLen = material.cohScatterLength();
429
430 // A material needs to be provided in order to calculate G_K(r)
431 if (PDFType == "G_k(r)" && cohScatLen == 0.0) {
432 std::stringstream msg;
433 msg << "Coherent Scattering Length is zero. Please check a sample material has been specified";
434 throw std::runtime_error(msg.str());
435 }
436
437 // convert to S(Q)-1 or g(R)+1
438 if (direction == FORWARD) {
439 convertToSQMinus1(inputY, inputX, inputDY, inputDX);
440 } else if (direction == BACKWARD) {
441 convertToLittleGRMinus1(inputY, inputX, inputDY, inputDX, PDFType, rho0, cohScatLen);
442 }
443
444 double inMin, inMax, outDelta, outMin, outMax;
445 inMin = getProperty("Qmin");
446 inMax = getProperty("Qmax");
447 outDelta = getProperty("DeltaR");
448 outMin = getProperty("Rmin");
449 outMax = getProperty("Rmax");
450 if (isEmpty(outMax)) {
451 outMax = 20;
452 }
453 if (direction == BACKWARD) {
454 inMin = getProperty("Rmin");
455 inMax = getProperty("Rmax");
456 outDelta = getProperty("DeltaQ");
457 outMin = getProperty("Qmin");
458 outMax = getProperty("Qmax");
459 if (isEmpty(outMax)) {
460 outMax = 40;
461 }
462 }
463 if (isEmpty(outMin)) {
464 outMin = 0;
465 }
466
467 // determine input-range
468 size_t Xmin_index = determineMinIndex(inMin, inputX, inputY);
469 size_t Xmax_index = determineMaxIndex(inMax, inputX, inputY);
470 g_log.notice() << "Adjusting to data: input min = " << inputX[Xmin_index] << " input max = " << inputX[Xmax_index]
471 << "\n";
472 // determine r axis for result
473 if (isEmpty(outDelta))
474 outDelta = M_PI / inputX[Xmax_index];
475 auto sizer = static_cast<size_t>((outMax - outMin) / outDelta);
476
477 bool filter = getProperty("Filter");
478
479 // create the output workspace
480
481 API::MatrixWorkspace_sptr outputWS = create<Workspace2D>(1, Points(sizer));
482 outputWS->copyExperimentInfoFrom(inputWS.get());
483 if (direction == FORWARD) {
484 outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("AtomicDistance");
485 outputWS->setYUnitLabel("PDF");
486 outputWS->mutableRun().addProperty("Qmin", inputX[Xmin_index], "Angstroms^-1", true);
487 outputWS->mutableRun().addProperty("Qmax", inputX[Xmax_index], "Angstroms^-1", true);
488 } else if (direction == BACKWARD) {
489 outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("MomentumTransfer");
490 outputWS->setYUnitLabel("Spectrum Density");
491 outputWS->mutableRun().addProperty("Rmin", inputX[Xmin_index], "Angstroms", true);
492 outputWS->mutableRun().addProperty("Rmax", inputX[Xmax_index], "Angstroms", true);
493 }
494 outputWS->setDistribution(true);
495 BinEdges edges(sizer + 1, LinearGenerator(outMin + outDelta / 2, outDelta));
496 outputWS->setBinEdges(0, edges);
497 auto &outputX = outputWS->mutableX(0);
498 g_log.information() << "Using output min = " << outputX.front() << " and output max = " << outputX.back() << "\n";
499 // always calculate G(r) then convert
500 auto &outputY = outputWS->mutableY(0);
501 auto &outputE = outputWS->mutableE(0);
502
503 // do the math
504 // Evaluate integral of Qsin(QR) over the Q bin width rather than just take value at bin centre
505 // Useful if Q bins widths are large - width typically increases with Q for TOF data. Following Gudrun approach
506
507 double corr = 0.5 / M_PI / M_PI / rho0;
508 if (direction == BACKWARD) {
509 corr = 4.0 * M_PI * rho0;
510 }
511 const double inXMax = inputX[Xmax_index];
512 for (size_t outXIndex = 0; outXIndex < sizer; outXIndex++) {
513 const double outX = 0.5 * (outputX[outXIndex] + outputX[outXIndex + 1]);
514 const double outXFac = corr / (outX * outX * outX);
515
516 double fs = 0;
517 double errorSquared = 0;
518 auto pdfIntegral = [outX](const double x) -> double { return sin(x * outX) - x * outX * cos(x * outX); };
519 double inX2 = inputX[Xmin_index];
520 double integralX2 = pdfIntegral(inX2);
521
522 for (size_t inXIndex = Xmin_index; inXIndex < Xmax_index; inXIndex++) {
523 const double inX1 = inX2;
524 inX2 = inputX[inXIndex + 1];
525 const double integralX1 = integralX2;
526 integralX2 = pdfIntegral(inX2);
527 double defIntegral = integralX2 - integralX1;
528
529 // multiply by filter function sin(q*pi/qmax)/(q*pi/qmax)
530 auto inXCen = 0.5 * (inX1 + inX2);
531 if (filter && fabs(inXCen) > 1e-8) {
532 const double lorchKernel = inXCen * M_PI / inXMax;
533 defIntegral *= sin(lorchKernel) / lorchKernel;
534 }
535 fs += defIntegral * inputY[inXIndex];
536
537 const double error = defIntegral * inputDY[inXIndex];
538 errorSquared += error * error;
539 }
540
541 // put the information into the output
542 outputY[outXIndex] = fs * outXFac;
543 outputE[outXIndex] = sqrt(errorSquared) * outXFac;
544 }
545
546 if (direction == FORWARD) {
547 convertFromLittleGRMinus1(outputY, outputX, outputE, PDFType, rho0, cohScatLen);
548 } else if (direction == BACKWARD) {
549 convertFromSQMinus1(outputY, outputX, outputE);
550 }
551
552 // set property
553 setProperty("OutputWorkspace", outputWS);
554}
555
556} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double error
#define fabs(x)
Definition Matrix.cpp:22
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Kernel::Logger & g_log
Definition Algorithm.h:422
bool isDefault(const std::string &name) const
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A property class for workspaces.
void init() override
Initialize the properties.
size_t determineMinIndex(double min, const std::vector< double > &X, const std::vector< double > &Y)
void convertToLittleGRMinus1(std::vector< double > &FOfR, const std::vector< double > &R, std::vector< double > &DFOfR, const std::vector< double > &DR, const std::string &PDFType, const double &rho0, const double &cohScatLen)
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
int version() const override
Algorithm's version for identification.
size_t determineMaxIndex(double max, const std::vector< double > &X, const std::vector< double > &Y)
void convertFromSQMinus1(HistogramData::HistogramY &FOfQ, const HistogramData::HistogramX &Q, HistogramData::HistogramE &DFOfQ)
const std::string category() const override
Algorithm's category for identification.
void convertFromLittleGRMinus1(HistogramData::HistogramY &FOfR, const HistogramData::HistogramX &R, HistogramData::HistogramE &DFOfR, const std::string &PDFType, const double &rho0, const double &cohScatLen)
void convertToSQMinus1(std::vector< double > &FOfQ, std::vector< double > &Q, std::vector< double > &DFOfQ, const std::vector< double > &DQ)
const std::string name() const override
Algorithm's name for identification.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings const > settings)
Add a PropertySettings instance to the chain of settings for a given property.
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
double cohScatterLength(const double lambda=PhysicalConstants::NeutronAtom::ReferenceLambda) const
Get the coherent scattering length for a given wavelength in fm.
Definition Material.cpp:328
double numberDensity() const
Get the number density.
Definition Material.cpp:189
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54