Mantid
Loading...
Searching...
No Matches
LatticeDomainCreator.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
10
14#include "MantidAPI/TableRow.h"
16
19
20namespace Mantid::CurveFitting {
21
22using namespace API;
23using namespace Kernel;
24using namespace DataObjects;
25using namespace CurveFitting::Algorithms;
26
28LatticeDomainCreator::LatticeDomainCreator(Kernel::IPropertyManager *manager, const std::string &workspacePropertyName,
30 : IDomainCreator(manager, std::vector<std::string>(1, workspacePropertyName), domainType),
31 m_workspacePropertyName(m_workspacePropertyNames.front()), m_workspace() {}
32
48void LatticeDomainCreator::createDomain(std::shared_ptr<API::FunctionDomain> &domain,
49 std::shared_ptr<API::FunctionValues> &values, size_t i0) {
51
52 API::IPeaksWorkspace_sptr peaksWorkspace = std::dynamic_pointer_cast<IPeaksWorkspace>(m_workspace);
53 if (peaksWorkspace) {
54 createDomainFromPeaksWorkspace(peaksWorkspace, domain, values, i0);
55 } else {
56 API::ITableWorkspace_sptr tableWorkspace = std::dynamic_pointer_cast<ITableWorkspace>(m_workspace);
57 if (tableWorkspace) {
58 createDomainFromPeakTable(tableWorkspace, domain, values, i0);
59 }
60 }
61}
62
78 std::shared_ptr<FunctionDomain> domain,
79 std::shared_ptr<FunctionValues> values,
80 const std::string &outputWorkspacePropertyName) {
81
82 std::shared_ptr<LatticeDomain> latticeDomain = std::dynamic_pointer_cast<LatticeDomain>(domain);
83 if (!latticeDomain) {
84 throw std::invalid_argument("LatticeDomain is required.");
85 }
86
87 ILatticeFunction_sptr latticeFunction = std::dynamic_pointer_cast<ILatticeFunction>(function);
88 if (!latticeFunction) {
89 throw std::invalid_argument("LatticeDomainCreator can only process ILatticeFunction.");
90 }
91
92 // Calculate function values again.
93 latticeFunction->functionLattice(*latticeDomain, *values);
94
95 ITableWorkspace_sptr tableWorkspace = WorkspaceFactory::Instance().createTable();
96
97 if (tableWorkspace) {
98 tableWorkspace->addColumn("V3D", "HKL");
99 tableWorkspace->addColumn("double", "d(obs)");
100 tableWorkspace->addColumn("double", "d(calc)");
101 tableWorkspace->addColumn("double", "d(obs) - d(calc)");
102
103 for (size_t i = 0; i < values->size(); ++i) {
104 double dObs = values->getFitData(i);
105 double dCalc = values->getCalculated(i);
106
107 TableRow newRow = tableWorkspace->appendRow();
108 newRow << (*latticeDomain)[i] << dObs << dCalc << dObs - dCalc;
109 }
110 }
111
112 if (m_manager && !outputWorkspacePropertyName.empty()) {
114 "Result workspace");
115
116 m_manager->setPropertyValue(outputWorkspacePropertyName, baseName + "Workspace");
117 m_manager->setProperty(outputWorkspacePropertyName, tableWorkspace);
118 }
119
120 return tableWorkspace;
121}
122
124 API::IPeaksWorkspace_sptr peaksWorkspace = std::dynamic_pointer_cast<IPeaksWorkspace>(m_workspace);
125 if (peaksWorkspace) {
126 return peaksWorkspace->getNumberPeaks();
127 }
128
129 API::ITableWorkspace_sptr tableWorkspace = std::dynamic_pointer_cast<ITableWorkspace>(m_workspace);
130 if (tableWorkspace) {
131 return tableWorkspace->rowCount();
132 }
133
134 return 0;
135}
136
139 if (!m_manager) {
140 throw std::invalid_argument("PropertyManager not set in LatticeDomainCreator.");
141 }
142
143 try {
145 } catch (const Kernel::Exception::NotFoundError &) {
146 throw std::invalid_argument("Could not extract workspace from PropertyManager.");
147 }
148}
149
152 std::shared_ptr<API::FunctionDomain> &domain,
153 std::shared_ptr<API::FunctionValues> &values, size_t i0) {
154 if (!workspace) {
155 throw std::invalid_argument("This function only works on an IPeaksWorkspace-object.");
156 }
157
158 size_t peakCount = workspace->getNumberPeaks();
159
160 if (peakCount < 1) {
161 throw std::range_error("Cannot create a domain for 0 peaks.");
162 }
163
164 std::vector<V3D> hkls;
165 hkls.reserve(peakCount);
166
167 std::vector<double> dSpacings;
168 dSpacings.reserve(peakCount);
169
170 for (size_t i = 0; i < peakCount; ++i) {
171 Geometry::IPeak *currentPeak = workspace->getPeakPtr(static_cast<int>(i));
172 V3D hkl = currentPeak->getHKL();
173
174 if (hkl != V3D(0, 0, 0)) {
175 hkls.emplace_back(hkl);
176 dSpacings.emplace_back(currentPeak->getDSpacing());
177 }
178 }
179
180 auto latticeDomain = new LatticeDomain(hkls);
181 domain.reset(latticeDomain);
182
183 if (!values) {
184 auto functionValues = new FunctionValues(*domain);
185 values.reset(functionValues);
186 } else {
187 values->expand(i0 + latticeDomain->size());
188 }
189
190 values->setFitData(dSpacings);
191
192 // Set unit weights.
193 values->setFitWeights(1.0);
194}
195
211 std::shared_ptr<FunctionDomain> &domain,
212 std::shared_ptr<FunctionValues> &values, size_t i0) {
213
214 size_t peakCount = workspace->rowCount();
215
216 if (peakCount < 1) {
217 throw std::range_error("Cannot create a domain for 0 peaks.");
218 }
219
220 try {
221 Column_const_sptr hklColumn = workspace->getColumn("HKL");
222 Column_const_sptr dColumn = workspace->getColumn("d");
223
224 std::vector<V3D> hkls;
225 hkls.reserve(peakCount);
226
227 std::vector<double> dSpacings;
228 dSpacings.reserve(peakCount);
229
231
232 for (size_t i = 0; i < peakCount; ++i) {
233 try {
234 V3D hkl = extractor(hklColumn, i);
235
236 if (hkl != V3D(0, 0, 0)) {
237 hkls.emplace_back(hkl);
238
239 double d = (*dColumn)[i];
240 dSpacings.emplace_back(d);
241 }
242 } catch (const std::bad_alloc &) {
243 // do nothing.
244 }
245 }
246
247 domain = std::make_shared<LatticeDomain>(hkls);
248 if (!values) {
249 values = std::make_shared<FunctionValues>(*domain);
250 } else {
251 values->expand(i0 + domain->size());
252 }
253
254 values->setFitData(dSpacings);
255
256 values->setFitWeights(1.0);
257 } catch (const std::runtime_error &) {
258 // Column does not exist
259 throw std::runtime_error("Can not process table, the following columns are "
260 "required: HKL, d.");
261 }
262}
263
264} // namespace Mantid::CurveFitting
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
A class to store values calculated by a function.
An base class for domain creators for use in Fit.
DomainType
Type of domain to create.
Kernel::IPropertyManager * m_manager
Pointer to a property manager.
void declareProperty(Kernel::Property *prop, const std::string &doc)
Declare a property to the algorithm.
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
A property class for workspaces.
API::Workspace_sptr createOutputWorkspace(const std::string &baseName, API::IFunction_sptr function, std::shared_ptr< API::FunctionDomain > domain, std::shared_ptr< API::FunctionValues > values, const std::string &outputWorkspacePropertyName) override
Creates an output workspace from calculated and observed values.
void createDomainFromPeakTable(const API::ITableWorkspace_sptr &workspace, std::shared_ptr< API::FunctionDomain > &domain, std::shared_ptr< API::FunctionValues > &values, size_t i0)
Creates a domain from an ITableWorkspace.
void createDomainFromPeaksWorkspace(const API::IPeaksWorkspace_sptr &workspace, std::shared_ptr< API::FunctionDomain > &domain, std::shared_ptr< API::FunctionValues > &values, size_t i0)
Creates a LatticeDomain from an IPeaksWorkspace, using HKL and d-values.
void createDomain(std::shared_ptr< API::FunctionDomain > &domain, std::shared_ptr< API::FunctionValues > &values, size_t i0) override
Creates a LatticeDomain from the assigned Workspace.
LatticeDomainCreator(Kernel::IPropertyManager *manager, const std::string &workspacePropertyName, DomainType domainType=Simple)
Constructor.
void setWorkspaceFromPropertyManager()
Get the workspace with peak data from the property manager.
size_t getDomainSize() const override
Return the size of the domain to be created.
Structure describing a single-crystal peak.
Definition: IPeak.h:26
virtual double getDSpacing() const =0
virtual Mantid::Kernel::V3D getHKL() const =0
Exception for when an item is not found in a collection.
Definition: Exception.h:145
Interface to PropertyManager.
virtual void setPropertyValue(const std::string &name, const std::string &value)=0
Sets property value from a string.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
virtual TypedValue getProperty(const std::string &name) const =0
Get the value of a property.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition: V3D.h:34
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< ILatticeFunction > ILatticeFunction_sptr
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition: IFunction.h:732
std::shared_ptr< const Column > Column_const_sptr
Definition: Column.h:229
STL namespace.
Small helper class to extract HKLs as V3D from table columns.
Definition: PawleyFit.h:27
@ Output
An output workspace.
Definition: Property.h:54