13#include <unordered_map>
22const static std::string
IO_MAP(
"InputOutputMap");
34 const auto f = s.front();
35 const auto b = s.back();
36 return (f ==
'\'' && b ==
'\'') || (f ==
'"' && b ==
'"');
46 throw std::runtime_error(
"Workspace name is too short.");
48 return std::string(s.cbegin() + 1, s.cend() - 1);
63 for (
const auto &ioPair : ioMapping) {
64 Column_sptr inputColumn = table->getColumn(ioPair.first);
65 Column_sptr outputColumn = table->getColumn(ioPair.second);
66 for (
size_t i = 0; i < table->rowCount(); ++i) {
67 inputColumn->cell<std::string>(i).clear();
68 auto &outputValue = outputColumn->cell<std::string>(i);
77 for (
const auto &ioPair : ioMapping) {
78 Column_sptr outputColumn = table->getColumn(ioPair.second);
79 for (
size_t i = 0; i < table->rowCount(); ++i) {
80 auto &outputValue = outputColumn->cell<std::string>(i);
93 "Name of the algorithm to run");
96 "Table workspace containing the setup of the runs.");
99 "Table workspace mapping algorithm outputs to inputs.");
107 if (ioMappingTable->rowCount() != 1) {
113 std::unordered_map<std::string, std::string> ioMap;
114 const auto inputPropertyNames = ioMappingTable->getColumnNames();
115 for (
size_t col = 0; col < ioMappingTable->columnCount(); ++col) {
116 const auto &inputPropertyName = ioMappingTable->getColumn(col)->name();
117 const auto &outputPropertyName = ioMappingTable->String(0, col);
118 if (!outputPropertyName.empty()) {
119 if (std::find(inputPropertyNames.cbegin(), inputPropertyNames.cend(), outputPropertyName) !=
120 inputPropertyNames.cend()) {
121 throw std::runtime_error(
"Property " + outputPropertyName +
" linked to " + inputPropertyName +
122 " is also an input property.");
124 if (ioMap.find(inputPropertyName) != ioMap.end()) {
125 throw std::runtime_error(
"Cannot assign more than one output to " + inputPropertyName +
'.');
127 ioMap[inputPropertyName] = outputPropertyName;
132 std::deque<size_t> queue;
133 for (
size_t i = 0; i < setupTable->rowCount(); ++i) {
134 configureRow(setupTable, propertyTable, i, queue, ioMap);
140 while (!queue.empty()) {
141 const auto row = queue.front();
142 auto algorithm = algorithmFactory.create(algorithmName, algorithmFactory.highestVersion(algorithmName));
143 algorithm->initialize();
144 if (!algorithm->isInitialized()) {
145 throw std::runtime_error(
"Workflow algorithm failed to initialise.");
148 for (
size_t col = 1; col < propertyTable->columnCount(); ++col) {
149 const auto column = propertyTable->getColumn(col);
150 const auto &propertyName = column->name();
151 const auto &valueType = column->get_type_info();
153 if (valueType ==
typeid(std::string)) {
154 const auto &
value = propertyTable->cell<std::string>(row, col);
155 algorithm->setProperty(propertyName,
value);
156 }
else if (valueType ==
typeid(
int)) {
157 const auto &
value = propertyTable->cell<
int>(row, col);
158 algorithm->setProperty(propertyName,
static_cast<long>(
value));
159 }
else if (valueType ==
typeid(
size_t)) {
160 const auto &
value = propertyTable->cell<
size_t>(row, col);
161 algorithm->setProperty(propertyName,
value);
162 }
else if (valueType ==
typeid(
float) || valueType ==
typeid(double)) {
163 const auto &
value = propertyTable->cell<
double>(row, col);
164 algorithm->setProperty(propertyName,
value);
165 }
else if (valueType ==
typeid(
bool)) {
166 const auto &
value = propertyTable->cell<
bool>(row, col);
167 algorithm->setProperty(propertyName,
value);
169 const auto &
value = propertyTable->cell<
V3D>(row, col);
170 algorithm->setProperty(propertyName,
value);
173 valueType.name() +
'.');
175 }
catch (std::invalid_argument &e) {
176 throw std::runtime_error(
"While setting properties for algorithm " + algorithmName +
": " + e.what());
179 algorithm->execute();
180 if (!algorithm->isExecuted()) {
181 throw std::runtime_error(
"Workflow algorithm failed to execute.");
200template <
typename QUEUE,
typename MAP>
202 const size_t currentRow, QUEUE &queue,
const MAP &ioMap,
203 std::shared_ptr<std::unordered_set<size_t>> rowsBeingQueued)
const {
206 if (currentRow > setupTable->rowCount()) {
207 throw std::runtime_error(
"Current row " +
std::to_string(currentRow) +
" out of task table bounds " +
213 if (std::find(queue.cbegin(), queue.cend(), currentRow) != queue.cend()) {
219 if (!rowsBeingQueued) {
220 rowsBeingQueued.reset(
new std::unordered_set<size_t>());
222 const auto status = rowsBeingQueued->emplace(currentRow);
223 if (!status.second) {
224 throw std::runtime_error(
"Circular dependencies!");
232 for (
const auto &ioPair : ioMap) {
233 const auto &outputId = setupTable->getRef<std::string>(ioPair.first, currentRow);
234 if (!outputId.empty()) {
237 propertyTable->getRef<std::string>(ioPair.first, currentRow) =
tidyWorkspaceName(outputId);
241 size_t outputRow = -1;
243 setupTable->find(outputId, outputRow, 0);
244 }
catch (std::out_of_range &) {
246 " (referenced in row " +
std::to_string(currentRow) +
", column \"" + ioPair.first +
250 configureRow(setupTable, propertyTable, outputRow, queue, ioMap, rowsBeingQueued);
251 const auto outputCol = ioPair.second;
252 auto outputWorkspaceName = setupTable->getRef<std::string>(outputCol, outputRow);
253 if (outputWorkspaceName.empty()) {
254 throw std::runtime_error(
"No source workspace name found for " + ioPair.first +
'.');
260 propertyTable->getRef<std::string>(ioPair.first, currentRow) = outputWorkspaceName;
261 propertyTable->getRef<std::string>(outputCol, outputRow) = outputWorkspaceName;
268 queue.emplace_back(currentRow);
271 rowsBeingQueued->erase(currentRow);
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
A property class for workspaces.
Controls the data flow and the order of algorithm execution.
void exec() override
Execution code.
void configureRow(API::ITableWorkspace_sptr setupTable, API::ITableWorkspace_sptr propertyTable, const size_t currentRow, QUEUE &queue, const MAP &ioMap, std::shared_ptr< std::unordered_set< size_t > > rowsBeingQueued=nullptr) const
Configures a row in setupTable.
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< Column > Column_sptr
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
static const std::string IO_MAP("InputOutputMap")
static const std::string SETUP_TABLE("SetupTable")
static const std::string ALGORITHM("Algorithm")
std::string tidyWorkspaceName(const std::string &s)
Removes first and last character of a string.
bool isHardCodedWorkspaceName(const std::string &s)
Checks if a string is a hard coded workspace name.
void cleanPropertyTable(const ITableWorkspace_sptr &table, const MAP &ioMapping)
Transforms a setup table to an empty property table.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.