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