23#include <boost/algorithm/string/classification.hpp>
24#include <boost/algorithm/string/split.hpp>
25#include <boost/algorithm/string/trim.hpp>
32using namespace Kernel;
33using namespace Geometry;
41const std::string PawleyFit::summary()
const {
42 return "This algorithm performs a Pawley-fit on the supplied workspace.";
46double PawleyFit::getTransformedCenter(
double d,
const Unit_sptr &unit)
const {
47 if (std::dynamic_pointer_cast<Units::Empty>(unit) || std::dynamic_pointer_cast<Units::dSpacing>(unit)) {
77 const Unit_sptr &unit,
double startX,
double endX)
const {
78 if (!tableWs || !pawleyFn) {
79 throw std::invalid_argument(
"Can only process non-null function & table.");
82 pawleyFn->clearPeaks();
92 for (
size_t i = 0; i < tableWs->rowCount(); ++i) {
94 V3D hkl = extractor(hklColumn, i);
96 double d = (*dColumn)[i];
98 double fwhm = (*fwhmColumn)[i] * center;
99 double height = (*intensityColumn)[i];
101 if (center > startX && center < endX) {
102 pawleyFn->addPeak(hkl, fwhm,
height);
104 }
catch (
const std::bad_alloc &) {
108 }
catch (
const std::runtime_error &) {
110 throw std::runtime_error(
"Can not process table, the following columns are "
111 "required: HKL, d, Intensity, FWHM (rel.)");
119 throw std::invalid_argument(
"Cannot extract lattice parameters from null function.");
124 latticeParameterTable->addColumn(
"str",
"Parameter");
125 latticeParameterTable->addColumn(
"double",
"Value");
126 latticeParameterTable->addColumn(
"double",
"Error");
130 for (
size_t i = 0; i < parameters->nParams(); ++i) {
131 TableRow newRow = latticeParameterTable->appendRow();
132 newRow << parameters->parameterName(i) << parameters->getParameter(i) << parameters->getError(i);
135 return latticeParameterTable;
141 throw std::invalid_argument(
"Cannot extract peak parameters from null function.");
146 peakParameterTable->addColumn(
"int",
"Peak");
147 peakParameterTable->addColumn(
"V3D",
"HKL");
148 peakParameterTable->addColumn(
"str",
"Parameter");
149 peakParameterTable->addColumn(
"double",
"Value");
150 peakParameterTable->addColumn(
"double",
"Error");
152 for (
size_t i = 0; i < pawleyFn->getPeakCount(); ++i) {
156 auto peakNumber =
static_cast<int>(i + 1);
157 V3D peakHKL = pawleyFn->getPeakHKL(i);
159 for (
size_t j = 0; j < currentPeak->nParams(); ++j) {
160 TableRow newRow = peakParameterTable->appendRow();
161 newRow << peakNumber << peakHKL << currentPeak->parameterName(j) << currentPeak->getParameter(j)
162 << currentPeak->getError(j);
166 return peakParameterTable;
173 composite->addFunction(pawleyFn);
175 bool enableChebyshev =
getProperty(
"EnableChebyshevBackground");
176 if (enableChebyshev) {
177 int degree =
getProperty(
"ChebyshevBackgroundDegree");
179 chebyshev->setAttributeValue(
"n", degree);
181 composite->addFunction(chebyshev);
188void PawleyFit::init() {
190 "Input workspace that contains the spectrum on which to "
191 "perform the Pawley fit.");
193 declareProperty(
"WorkspaceIndex", 0,
"Spectrum on which the fit should be performed.");
198 std::vector<std::string> latticeSystems{
"Cubic",
"Tetragonal",
"Hexagonal",
"Rhombohedral",
199 "Orthorhombic",
"Monoclinic",
"Triclinic"};
201 auto latticeSystemValidator = std::make_shared<StringListValidator>(latticeSystems);
203 declareProperty(
"LatticeSystem", latticeSystems.back(), latticeSystemValidator,
204 "Lattice system to use for refinement.");
207 "Specification of initial unit cell, given as 'a, b, c, "
208 "alpha, beta, gamma'.");
211 "Table with peak information. Can be used instead of "
212 "supplying a list of indices for better starting parameters.");
215 "If checked, a zero-shift with the "
216 "same unit as the spectrum is "
219 auto peakFunctionValidator =
222 declareProperty(
"PeakProfileFunction",
"Gaussian", peakFunctionValidator,
223 "Profile function that is used for each peak.");
226 "If checked, a Chebyshev "
227 "polynomial will be added "
228 "to model the background.");
230 declareProperty(
"ChebyshevBackgroundDegree", 0,
"Degree of the Chebyshev polynomial, if used as background.");
233 "If enabled, no fit is performed, "
234 "the function is only evaluated "
235 "and output is generated.");
238 "Workspace that contains measured spectrum, calculated "
239 "spectrum and difference curve.");
242 "TableWorkspace with refined lattice parameters, including errors.");
246 "TableWorkspace with refined peak parameters, including errors.");
249 "Outputs the reduced chi square "
250 "value as a measure for the quality "
258void PawleyFit::exec() {
264 std::string profileFunction =
getProperty(
"PeakProfileFunction");
265 pawleyFn->setProfileFunction(profileFunction);
266 g_log.
information() <<
" Selected profile function: " << profileFunction <<
'\n';
268 std::string latticeSystem =
getProperty(
"LatticeSystem");
269 pawleyFn->setLatticeSystem(latticeSystem);
270 g_log.
information() <<
" Selected crystal system: " << latticeSystem <<
'\n';
282 const auto &xData = ws->x(
static_cast<size_t>(wsIndex));
283 double startX = xData.front();
284 double endX = xData.back();
289 startX = std::max(startX, startXInput);
295 endX = std::min(endX, endXInput);
298 g_log.
information() <<
" Refined range: " << startX <<
" - " << endX <<
'\n';
302 Axis *xAxis = ws->getAxis(0);
306 g_log.
information() <<
" Peaks in PawleyFunction: " << pawleyFn->getPeakCount() <<
'\n';
309 bool refineZeroShift =
getProperty(
"RefineZeroShift");
310 if (!refineZeroShift) {
311 pawleyFn->fix(pawleyFn->parameterIndex(
"f0.ZeroShift"));
316 pawleyFn->setMatrixWorkspace(ws,
static_cast<size_t>(wsIndex), startX, endX);
323 fit->setProperty(
"InputWorkspace", std::const_pointer_cast<MatrixWorkspace>(ws));
324 fit->setProperty(
"StartX", startX);
325 fit->setProperty(
"EndX", endX);
326 fit->setProperty(
"WorkspaceIndex", wsIndex);
328 bool calculationOnly =
getProperty(
"CalculationOnly");
329 if (calculationOnly) {
330 fit->setProperty(
"MaxIterations", 0);
333 fit->setProperty(
"CreateOutput",
true);
336 double chiSquare = fit->getProperty(
"OutputChi2overDoF");
338 g_log.
information() <<
"Fit finished, reduced ChiSquare = " << chiSquare <<
'\n';
353 if (hklColumn->type() ==
"V3D") {
362 return hklColumn->cell<
V3D>(i);
372V3D V3DFromHKLColumnExtractor::getHKLFromString(
const std::string &hklString)
const {
373 auto delimiters = boost::is_any_of(
" ,[];");
375 std::string workingCopy = boost::trim_copy_if(hklString, delimiters);
376 std::vector<std::string> indicesStr;
377 boost::split(indicesStr, workingCopy, delimiters);
379 if (indicesStr.size() != 3) {
380 throw std::invalid_argument(
"Input string cannot be parsed as HKL.");
384 hkl.
setX(boost::lexical_cast<double>(indicesStr[0]));
385 hkl.
setY(boost::lexical_cast<double>(indicesStr[1]));
386 hkl.
setZ(boost::lexical_cast<double>(indicesStr[2]));
#define DECLARE_ALGORITHM(classname)
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Kernel::Property * getPointerToProperty(const std::string &name) const override
Get a property by name.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Class to represent the axis of a workspace.
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
This algorithm uses the Pawley-method to refine lattice parameters using a powder diffractogram and a...
API::ITableWorkspace_sptr getLatticeFromFunction(const Functions::PawleyFunction_sptr &pawleyFn) const
Creates a table containing the cell parameters stored in the supplied function.
API::IFunction_sptr getCompositeFunction(const Functions::PawleyFunction_sptr &pawleyFn) const
Returns a composite function consisting of the Pawley function and Chebyshev background if enabled in...
void addHKLsToFunction(Functions::PawleyFunction_sptr &pawleyFn, const API::ITableWorkspace_sptr &tableWs, const Kernel::Unit_sptr &unit, double startX, double endX) const
Add HKLs from a TableWorkspace to the PawleyFunction.
double getTransformedCenter(double d, const Kernel::Unit_sptr &unit) const
Transforms the specified value from d-spacing to the supplied unit.
Kernel::Unit_sptr m_dUnit
API::ITableWorkspace_sptr getPeakParametersFromFunction(const Functions::PawleyFunction_sptr &pawleyFn) const
Extracts all profile parameters from the supplied function.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void information(const std::string &msg)
Logs at information level.
Base class for properties.
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
static double run(const std::string &src, const std::string &dest, const double srcValue, const double l1, const double l2, const double theta, const DeltaEMode::Type emode, const double efixed)
Convert a single value between the given units (as strings)
void setZ(const double zz) noexcept
Set is z position.
void setX(const double xx) noexcept
Set is x position.
void setY(const double yy) noexcept
Set is y position.
std::shared_ptr< IPeakFunction > IPeakFunction_sptr
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< const Column > Column_const_sptr
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
std::shared_ptr< PawleyFunction > PawleyFunction_sptr
std::shared_ptr< PawleyParameterFunction > PawleyParameterFunction_sptr
MANTID_GEOMETRY_DLL std::string unitCellToStr(const UnitCell &unitCell)
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
Small helper class to extract HKLs as V3D from table columns.
Kernel::V3D getHKLFromV3DColumn(const API::Column_const_sptr &hklColumn, size_t i) const
Returns the i-th cell of a V3D column.
Kernel::V3D getHKLFromString(const std::string &hklString) const
Try to extract a V3D from the given string with different separators.
Kernel::V3D getHKLFromStringColumn(const API::Column_const_sptr &hklColumn, size_t i) const
Pass the cell value as string to getHKLFromString.
@ Input
An input workspace.
@ Output
An output workspace.