64 for (
const auto &ioPair : ioMapping) {
65 Column_sptr inputColumn = table->getColumn(ioPair.first);
66 Column_sptr outputColumn = table->getColumn(ioPair.second);
67 for (
size_t i = 0; i < table->rowCount(); ++i) {
68 inputColumn->cell<std::string>(i).clear();
69 auto &outputValue = outputColumn->cell<std::string>(i);
78 for (
const auto &ioPair : ioMapping) {
79 Column_sptr outputColumn = table->getColumn(ioPair.second);
80 for (
size_t i = 0; i < table->rowCount(); ++i) {
81 auto &outputValue = outputColumn->cell<std::string>(i);
108 if (ioMappingTable->rowCount() != 1) {
114 std::unordered_map<std::string, std::string> ioMap;
115 const auto inputPropertyNames = ioMappingTable->getColumnNames();
116 for (
size_t col = 0; col < ioMappingTable->columnCount(); ++col) {
117 const auto &inputPropertyName = ioMappingTable->getColumn(col)->name();
118 const auto &outputPropertyName = ioMappingTable->String(0, col);
119 if (!outputPropertyName.empty()) {
120 if (std::find(inputPropertyNames.cbegin(), inputPropertyNames.cend(), outputPropertyName) !=
121 inputPropertyNames.cend()) {
122 throw std::runtime_error(
"Property " + outputPropertyName +
" linked to " + inputPropertyName +
123 " is also an input property.");
125 if (ioMap.find(inputPropertyName) != ioMap.end()) {
126 throw std::runtime_error(
"Cannot assign more than one output to " + inputPropertyName +
'.');
128 ioMap[inputPropertyName] = outputPropertyName;
133 std::deque<size_t> queue;
134 for (
size_t i = 0; i < setupTable->rowCount(); ++i) {
135 configureRow(setupTable, propertyTable, i, queue, ioMap);
140 auto &algorithmFactory = AlgorithmFactory::Instance();
141 while (!queue.empty()) {
142 const auto row = queue.front();
143 auto algorithm = algorithmFactory.create(algorithmName, algorithmFactory.highestVersion(algorithmName));
144 algorithm->initialize();
145 if (!algorithm->isInitialized()) {
146 throw std::runtime_error(
"Workflow algorithm failed to initialise.");
149 for (
size_t col = 1; col < propertyTable->columnCount(); ++col) {
150 const auto column = propertyTable->getColumn(col);
151 const auto &propertyName = column->name();
152 const auto &valueType = column->get_type_info();
154 if (valueType ==
typeid(std::string)) {
155 const auto &
value = propertyTable->cell<std::string>(row, col);
156 algorithm->setProperty(propertyName,
value);
157 }
else if (valueType ==
typeid(
int)) {
158 const auto &
value = propertyTable->cell<
int>(row, col);
159 algorithm->setProperty(propertyName,
static_cast<long>(
value));
160 }
else if (valueType ==
typeid(
size_t)) {
161 const auto &
value = propertyTable->cell<
size_t>(row, col);
162 algorithm->setProperty(propertyName,
value);
163 }
else if (valueType ==
typeid(
float) || valueType ==
typeid(double)) {
164 const auto &
value = propertyTable->cell<
double>(row, col);
165 algorithm->setProperty(propertyName,
value);
166 }
else if (valueType ==
typeid(
bool)) {
167 const auto &
value = propertyTable->cell<
bool>(row, col);
168 algorithm->setProperty(propertyName,
value);
170 const auto &
value = propertyTable->cell<
V3D>(row, col);
171 algorithm->setProperty(propertyName,
value);
174 valueType.name() +
'.');
176 }
catch (std::invalid_argument &e) {
177 throw std::runtime_error(
"While setting properties for algorithm " + algorithmName +
": " + e.what());
180 algorithm->execute();
181 if (!algorithm->isExecuted()) {
182 throw std::runtime_error(
"Workflow algorithm failed to execute.");
203 const size_t currentRow, QUEUE &queue,
const MAP &ioMap,
204 std::shared_ptr<std::unordered_set<size_t>> rowsBeingQueued)
const {
207 if (currentRow > setupTable->rowCount()) {
208 throw std::runtime_error(
"Current row " +
std::to_string(currentRow) +
" out of task table bounds " +
214 if (std::find(queue.cbegin(), queue.cend(), currentRow) != queue.cend()) {
220 if (!rowsBeingQueued) {
221 rowsBeingQueued.reset(
new std::unordered_set<size_t>());
223 const auto status = rowsBeingQueued->emplace(currentRow);
224 if (!status.second) {
225 throw std::runtime_error(
"Circular dependencies!");
233 for (
const auto &ioPair : ioMap) {
234 const auto &outputId = setupTable->getRef<std::string>(ioPair.first, currentRow);
235 if (!outputId.empty()) {
238 propertyTable->getRef<std::string>(ioPair.first, currentRow) =
tidyWorkspaceName(outputId);
242 size_t outputRow = -1;
244 setupTable->find(outputId, outputRow, 0);
245 }
catch (std::out_of_range &) {
247 " (referenced in row " +
std::to_string(currentRow) +
", column \"" + ioPair.first +
251 configureRow(setupTable, propertyTable, outputRow, queue, ioMap, rowsBeingQueued);
252 const auto outputCol = ioPair.second;
253 auto outputWorkspaceName = setupTable->getRef<std::string>(outputCol, outputRow);
254 if (outputWorkspaceName.empty()) {
255 throw std::runtime_error(
"No source workspace name found for " + ioPair.first +
'.');
261 propertyTable->getRef<std::string>(ioPair.first, currentRow) = outputWorkspaceName;
262 propertyTable->getRef<std::string>(outputCol, outputRow) = outputWorkspaceName;
269 queue.emplace_back(currentRow);
272 rowsBeingQueued->erase(currentRow);
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.