Mantid
Loading...
Searching...
No Matches
GeneralDomainCreator.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 +
11#include "MantidAPI/Workspace.h"
15
16namespace Mantid::CurveFitting {
17
18using namespace API;
19
28 const std::string &workspacePropertyName)
29 : IDomainCreator(&manager, std::vector<std::string>(1, workspacePropertyName)) {
30
32
33 auto nDomainColumns = fun.getNumberDomainColumns();
34 if (nDomainColumns > 0) {
35 m_domainColumnNames.emplace_back("ArgumentColumn");
36 for (size_t i = 1; i < nDomainColumns; ++i) {
37 m_domainColumnNames.emplace_back(m_domainColumnNames.front() + "_" + std::to_string(i));
38 }
39 }
40
41 auto nDataColumns = fun.getNumberValuesPerArgument();
42 if (nDataColumns > 0) {
43 m_dataColumnNames.emplace_back("DataColumn");
44 m_weightsColumnNames.emplace_back("WeightsColumn");
45 for (size_t i = 1; i < nDataColumns; ++i) {
46 auto si = "_" + std::to_string(i);
47 m_dataColumnNames.emplace_back(m_dataColumnNames.front() + si);
48 m_weightsColumnNames.emplace_back(m_weightsColumnNames.front() + si);
49 }
50 }
51}
52
58void GeneralDomainCreator::declareDatasetProperties(const std::string &suffix, bool addProp) {
59 UNUSED_ARG(suffix);
60 if (addProp) {
61 for (auto &propName : m_domainColumnNames) {
62 declareProperty(new Kernel::PropertyWithValue<std::string>(propName, ""), "A name of a domain column.");
63 }
64 for (auto &propName : m_dataColumnNames) {
65 declareProperty(new Kernel::PropertyWithValue<std::string>(propName, ""), "A name of a fitting data column.");
66 }
67 for (auto &propName : m_weightsColumnNames) {
68 declareProperty(new Kernel::PropertyWithValue<std::string>(propName, ""), "A name of a fitting weights column.");
69 }
70 }
71}
72
74std::shared_ptr<API::ITableWorkspace> GeneralDomainCreator::getInputWorkspace() const {
75 auto workspacePropertyName = m_workspacePropertyNames.front();
76 if (!m_manager->existsProperty(workspacePropertyName)) {
78 }
79 API::Workspace_sptr ws = m_manager->getProperty(workspacePropertyName);
80 auto tableWorkspace = std::dynamic_pointer_cast<API::ITableWorkspace>(ws);
81 if (!tableWorkspace) {
82 throw std::invalid_argument("InputWorkspace must be a TableWorkspace.");
83 }
84 return tableWorkspace;
85}
86
94void GeneralDomainCreator::createDomain(std::shared_ptr<FunctionDomain> &domain,
95 std::shared_ptr<FunctionValues> &values, size_t i0) {
96
97 // Create the values object
98 if (!values) {
99 values.reset(new FunctionValues);
100 }
101
102 // get the workspace
103 auto tableWorkspace = getInputWorkspace();
104
105 size_t domainSize = 0;
106 domain.reset(new FunctionDomainGeneral);
107 // Create the domain
108 if (!m_domainColumnNames.empty() && tableWorkspace) {
109 auto &generalDomain = *static_cast<FunctionDomainGeneral *>(domain.get());
110 for (auto &propName : m_domainColumnNames) {
111 std::string columnName = m_manager->getPropertyValue(propName);
112 auto column = tableWorkspace->getColumn(columnName);
113 generalDomain.addColumn(column);
114 }
115 domainSize = domain->size();
116 } else {
117 domainSize = m_defaultValuesSize;
118 }
119
120 // No workspace - no data
121 if (!tableWorkspace) {
122 return;
123 }
124
125 if (domainSize == 0) {
126 domainSize = tableWorkspace->rowCount();
127 }
128
129 // If domain size is 0 - there are no fitting data
130 if (domainSize == 0) {
131 return;
132 }
133
134 // Get the fitting data
135 auto nDataColumns = m_dataColumnNames.size();
136 // Append each column to values' fitting data
137 for (size_t i = 0; i < nDataColumns; ++i) {
138 // Set the data
139 std::string columnName = m_manager->getPropertyValue(m_dataColumnNames[i]);
140 auto dataColumn = tableWorkspace->getColumn(columnName);
141 values->expand(i0 + domainSize);
142 for (size_t j = 0; j < domainSize; ++j) {
143 values->setFitData(i0 + j, dataColumn->toDouble(j));
144 }
145 // Set the weights
147 if (!columnName.empty()) {
148 auto weightsColumn = tableWorkspace->getColumn(columnName);
149 for (size_t j = 0; j < domainSize; ++j) {
150 values->setFitWeight(i0 + j, weightsColumn->toDouble(j));
151 }
152 } else {
153 for (size_t j = 0; j < domainSize; ++j) {
154 values->setFitWeight(i0 + j, 1.0);
155 }
156 }
157 i0 += domainSize;
158 }
159}
160
174 std::shared_ptr<FunctionDomain> domain,
175 std::shared_ptr<FunctionValues> values,
176 const std::string &outputWorkspacePropertyName) {
177 if (function->getValuesSize(*domain) != values->size()) {
178 throw std::runtime_error("Failed to create output workspace: domain and "
179 "values object don't match.");
180 }
181 size_t rowCount = domain->size();
182 if (rowCount == 0) {
183 auto &generalFunction = dynamic_cast<IFunctionGeneral &>(*function);
184 rowCount = generalFunction.getDefaultDomainSize();
185 }
186
187 ITableWorkspace_sptr outputWorkspace;
188
189 auto inputWorkspace = getInputWorkspace();
190 // Clone the data and domain columns from inputWorkspace to outputWorkspace.
191 if (inputWorkspace) {
192 // Collect the names of columns to clone
193 std::vector<std::string> columnsToClone;
194 for (auto &propName : m_domainColumnNames) {
195 auto columnName = m_manager->getPropertyValue(propName);
196 columnsToClone.emplace_back(columnName);
197 }
198 for (auto &propName : m_dataColumnNames) {
199 auto columnName = m_manager->getPropertyValue(propName);
200 columnsToClone.emplace_back(columnName);
201 }
202 outputWorkspace = inputWorkspace->cloneColumns(columnsToClone);
203 if (rowCount != outputWorkspace->rowCount()) {
204 throw std::runtime_error("Cloned workspace has wrong number of rows.");
205 }
206
207 // Add columns with the calculated data
208 size_t i0 = 0;
209 for (auto &propName : m_dataColumnNames) {
210 auto dataColumnName = m_manager->getPropertyValue(propName);
211 auto calcColumnName = dataColumnName + "_calc";
212 auto column = outputWorkspace->addColumn("double", calcColumnName);
213 for (size_t row = 0; row < rowCount; ++row) {
214 auto value = values->getCalculated(i0 + row);
215 column->fromDouble(row, value);
216 }
217 i0 += rowCount;
218 }
219 } else {
220 outputWorkspace = API::WorkspaceFactory::Instance().createTable();
221 outputWorkspace->setRowCount(rowCount);
222 size_t i0 = 0;
223 for (auto &propName : m_dataColumnNames) {
224 auto calcColumnName = m_manager->getPropertyValue(propName);
225 if (calcColumnName.empty()) {
226 calcColumnName = propName;
227 }
228 auto column = outputWorkspace->addColumn("double", calcColumnName);
229 for (size_t row = 0; row < rowCount; ++row) {
230 auto value = values->getCalculated(i0 + row);
231 column->fromDouble(row, value);
232 }
233 i0 += rowCount;
234 }
235 }
236
237 if (!outputWorkspacePropertyName.empty()) {
240 "Name of the output Workspace holding resulting simulated values");
241 m_manager->setPropertyValue(outputWorkspacePropertyName, baseName + "Workspace");
242 m_manager->setProperty(outputWorkspacePropertyName, outputWorkspace);
243 }
244
245 return outputWorkspace;
246}
247
254 size_t domainSize = 0;
255 if (!m_domainColumnNames.empty()) {
256 auto inputWorkspace = getInputWorkspace();
257 domainSize = inputWorkspace->rowCount();
258 } else {
259 domainSize = m_defaultValuesSize;
260 }
261 return domainSize;
262}
263
264} // namespace Mantid::CurveFitting
double value
The value of the point.
Definition: FitMW.cpp:51
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
Represent a domain of a very general type.
A class to store values calculated by a function.
An base class for domain creators for use in Fit.
std::vector< std::string > m_workspacePropertyNames
Property names for workspaces to get the data from.
Kernel::IPropertyManager * m_manager
Pointer to a property manager.
void declareProperty(Kernel::Property *prop, const std::string &doc)
Declare a property to the algorithm.
IFunctionGeneral: a very general function definition.
virtual size_t getNumberDomainColumns() const =0
Get number of columns that the domain must have.
virtual size_t getDefaultDomainSize() const
Get the default size of a domain.
virtual size_t getNumberValuesPerArgument() const =0
Get number of values per argument in the domain.
A property class for workspaces.
void createDomain(std::shared_ptr< API::FunctionDomain > &domain, std::shared_ptr< API::FunctionValues > &values, size_t i0=0) override
Creates a domain corresponding to the assigned MatrixWorkspace.
std::vector< std::string > m_weightsColumnNames
Property names for columns in a TableWorkspace to be used as the fitting weights.
std::vector< std::string > m_dataColumnNames
Property names for columns in a TableWorkspace to be used as the data to fit to.
size_t getDomainSize() const override
Returns the domain size.
GeneralDomainCreator(const API::IFunctionGeneral &fun, Kernel::IPropertyManager &manager, const std::string &workspacePropertyName)
Constructor.
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="OutputWorkspace") override
Creates an output workspace using the given function and domain.
std::vector< std::string > m_domainColumnNames
Property names for columns in a TableWorkspace to be passed to the domain.
void declareDatasetProperties(const std::string &suffix="", bool addProp=true) override
Declare properties that specify the dataset within the workspace to fit to.
std::shared_ptr< API::ITableWorkspace > getInputWorkspace() const
Retrive the input workspace from the property manager.
size_t m_defaultValuesSize
Default number of values.
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 bool existsProperty(const std::string &name) const =0
Checks whether the named property is already in the list of managed property.
virtual TypedValue getProperty(const std::string &name) const =0
Get the value of a property.
virtual std::string getPropertyValue(const std::string &name) const =0
Get the value of a property as a string.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
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
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Output
An output workspace.
Definition: Property.h:54