21#include <boost/algorithm/string/predicate.hpp>
27template <
typename T,
typename... Ts> std::vector<T, Ts...> repeat(std::vector<T, Ts...>
const &vec, std::size_t
n) {
28 std::vector<T, Ts...> result;
29 result.reserve(vec.size() *
n);
31 result.insert(result.end(), vec.begin(), vec.end());
35template <
typename T> std::vector<T> getIncrementingSequence(
const T &from, std::size_t length) {
36 std::vector<T> sequence(length);
37 std::iota(sequence.begin(), sequence.end(), from);
41std::vector<std::string> appendSuffix(std::vector<std::string>
const &vec, std::string
const &suffix) {
42 std::vector<std::string> appended;
43 appended.reserve(vec.size());
44 std::transform(vec.cbegin(), vec.cend(), std::back_inserter(appended),
45 [&suffix](
auto &&str) { return str + suffix; });
50 std::vector<double>
const &e,
int numberOfSpectra,
51 std::vector<std::string>
const &verticalAxisNames, std::string
const &unitX) {
53 createWorkspaceAlgorithm->initialize();
54 createWorkspaceAlgorithm->setChild(
true);
55 createWorkspaceAlgorithm->setLogging(
false);
56 createWorkspaceAlgorithm->setProperty(
"DataX",
x);
57 createWorkspaceAlgorithm->setProperty(
"DataY",
y);
58 createWorkspaceAlgorithm->setProperty(
"DataE", e);
59 createWorkspaceAlgorithm->setProperty(
"NSpec", numberOfSpectra);
60 createWorkspaceAlgorithm->setProperty(
"VerticalAxisUnit",
"Text");
61 createWorkspaceAlgorithm->setProperty(
"VerticalAxisValues", verticalAxisNames);
62 createWorkspaceAlgorithm->setProperty(
"UnitX", unitX);
63 createWorkspaceAlgorithm->setProperty(
"OutputWorkspace",
"__created");
64 createWorkspaceAlgorithm->execute();
65 return createWorkspaceAlgorithm->getProperty(
"OutputWorkspace");
68template <
typename T,
typename OutputIterator>
69void extractColumnValues(
Column const &column, std::size_t startRow, std::size_t endRow, OutputIterator outputIt) {
70 for (
auto i = startRow; i <= endRow; ++i)
71 *outputIt++ = column.
cell<T>(i);
74template <
typename T,
typename OutputIterator>
75void extractValuesFromColumns(std::size_t startRow, std::size_t endRow,
const std::vector<Column_const_sptr> &columns,
76 OutputIterator outputIt) {
77 for (
auto &&column : columns)
78 extractColumnValues<T>(*column, startRow, endRow, outputIt);
81template <
typename T> std::vector<T> getColumnValues(
Column const &column, std::size_t startRow, std::size_t endRow) {
82 std::vector<T> values;
83 values.reserve(1 + (endRow - startRow));
84 extractColumnValues<T>(column, startRow, endRow, std::back_inserter(values));
88std::vector<double> getNumericColumnValuesOrIndices(
Column const &column, std::size_t startRow, std::size_t endRow) {
89 auto const length = startRow > endRow ? 0 : 1 + endRow - startRow;
91 return getColumnValues<double>(column, startRow, endRow);
92 return getIncrementingSequence(0.0, length);
95std::string getColumnName(
const Column_const_sptr &column) {
return column->name(); }
97std::vector<std::string> extractColumnNames(std::vector<Column_const_sptr>
const &columns) {
98 std::vector<std::string> names;
99 names.reserve(columns.size());
100 std::transform(columns.begin(), columns.end(), std::back_inserter(names), getColumnName);
104template <
typename ColumnFilter>
105std::vector<Column_const_sptr> extractColumns(
ITableWorkspace const *table, ColumnFilter
const &filter) {
106 std::vector<Column_const_sptr> columns;
110 columns.emplace_back(column);
115struct TableToMatrixWorkspaceConverter {
116 template <
typename YFilter,
typename EFilter>
117 TableToMatrixWorkspaceConverter(
ITableWorkspace const *table, std::vector<double>
x, YFilter
const &yFilter,
118 EFilter
const &eFilter)
119 : m_x(
std::move(
x)), m_yColumns(extractColumns(table, yFilter)), m_eColumns(extractColumns(table, eFilter)),
120 m_yAxis(extractColumnNames(m_yColumns)) {}
122 MatrixWorkspace_sptr operator()(std::size_t startRow, std::size_t endRow, std::string
const &unitX,
123 bool includeChiSquared)
const {
124 auto const x = repeat(m_x, m_yColumns.size());
126 std::vector<double>
y;
127 std::vector<double> e;
130 extractValuesFromColumns<double>(startRow, endRow, m_yColumns, std::back_inserter(
y));
131 extractValuesFromColumns<double>(startRow, endRow, m_eColumns, std::back_inserter(e));
133 if (includeChiSquared)
134 std::fill_n(std::back_inserter(e),
y.size() - e.size(), 0.0);
136 return createWorkspace(
x,
y, e,
static_cast<int>(m_yColumns.size()), m_yAxis, unitX);
140 std::vector<double>
const m_x;
141 std::vector<Column_const_sptr>
const m_yColumns;
142 std::vector<Column_const_sptr>
const m_eColumns;
143 std::vector<std::string>
const m_yAxis;
146struct EndsWithOneOf {
147 explicit EndsWithOneOf(std::vector<std::string> &&strings) : m_strings(
std::move(strings)) {}
149 bool operator()(std::string
const &
value)
const {
150 for (
auto &&str : m_strings) {
151 if (boost::algorithm::ends_with(
value, str))
158 std::vector<std::string>
const m_strings;
161template <
typename StringFilter>
struct ColumnNameFilter {
163 explicit ColumnNameFilter(StringFilter &&filter) : m_filter(
std::forward<StringFilter>(filter)) {}
165 bool operator()(
Column const &column)
const {
return m_filter(column.
name()); }
168 StringFilter
const m_filter;
171template <
typename StringFilter> ColumnNameFilter<StringFilter> makeColumnNameFilter(StringFilter &&filter) {
172 return ColumnNameFilter<StringFilter>(std::forward<StringFilter>(filter));
179using namespace Kernel;
197 return "Convert a parameter table output by PlotPeakByLogValue to a "
207 unitOptions.emplace_back(
"");
210 "The table workspace to convert to a MatrixWorkspace.");
217 "List of the parameter names to add to the workspace.");
219 declareProperty(
"IncludeChiSquared",
false,
"Add Chi-squared to the output workspace.");
221 declareProperty(
"XAxisUnit",
"", std::make_shared<StringListValidator>(unitOptions),
222 "The unit to assign to the X Axis");
224 auto positiveInt = std::make_shared<Kernel::BoundedValidator<int>>();
225 positiveInt->setLower(0);
227 "The start row index to include in the output matrix workspace.");
229 "The end row index to include in the output matrix workspace.");
232 "The name to give the output workspace");
241 std::string
const xUnit =
getProperty(
"XAxisUnit");
242 bool const includeChiSquared =
getProperty(
"IncludeChiSquared");
243 std::vector<std::string> parameterNames =
getProperty(
"ParameterNames");
244 std::vector<std::string> errorNames = appendSuffix(parameterNames,
"_Err");
246 auto const endRow =
getEndRow(inputWs->rowCount() - 1);
248 if (includeChiSquared)
249 parameterNames.emplace_back(
"Chi_squared");
251 auto const x = getNumericColumnValuesOrIndices(*inputWs->getColumn(xColumn), startRow, endRow);
252 auto const yFilter = makeColumnNameFilter(EndsWithOneOf(std::move(parameterNames)));
253 auto const eFilter = makeColumnNameFilter(EndsWithOneOf(std::move(errorNames)));
255 TableToMatrixWorkspaceConverter converter(inputWs.get(),
x, yFilter, eFilter);
256 auto const output = converter(startRow, endRow, xUnit, includeChiSquared);
262 return startRow ==
EMPTY_INT() ? 0 :
static_cast<std::size_t
>(startRow);
267 return endRow ==
EMPTY_INT() ? maximum :
static_cast<std::size_t
>(endRow);
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
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.
Column is the base class for columns of TableWorkspace.
T & cell(size_t index)
Templated method for returning a value. No type checks are done.
virtual bool isNumber() const =0
Are elements of the column interpretable as a number?
const std::string & name() const
Name (caption) of the column.
ITableWorkspace is an implementation of Workspace in which the data are organised in columns of same ...
virtual Column_sptr getColumn(const std::string &name)=0
Gets the shared pointer to a column by name.
virtual size_t columnCount() const =0
Number of columns in the workspace.
A property class for workspaces.
ProcessIndirectFitParameters : Convert a parameter table output by PlotPeakByLogValue to a MatrixWork...
std::size_t getEndRow(std::size_t maximum) const
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void exec() override
Execute the algorithm.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
std::size_t getStartRow() const
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Validator to check that a property is not left empty.
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< T > createWorkspace(InitArgs... args)
std::shared_ptr< const Column > Column_const_sptr
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
@ Input
An input workspace.
@ Output
An output workspace.