11#include <boost/algorithm/string.hpp>
12#include <boost/regex.hpp>
25 virtual bool isValid()
const {
return true; }
30 if (!this->isValid()) {
35 auto conjoinWorkspaceAlg = factory.
create(
"ConjoinWorkspaces");
36 conjoinWorkspaceAlg->setChild(
true);
37 conjoinWorkspaceAlg->initialize();
38 conjoinWorkspaceAlg->setProperty(
"InputWorkspace1", toAppend);
39 conjoinWorkspaceAlg->setProperty(
"InputWorkspace2", current);
40 conjoinWorkspaceAlg->execute();
46 virtual ~Command() =
default;
50using VecCommands = std::vector<std::shared_ptr<Command>>;
55class NullCommand :
public Command {
56 bool isValid()
const override {
return false; }
58 throw std::runtime_error(
"Should not be attempting ::execute on a NullCommand");
65class AdditionCommand :
public Command {
67 std::vector<int> m_indexes;
70 explicit AdditionCommand(std::vector<int> indexes) : m_indexes(
std::move(indexes)) {}
74 if (!m_indexes.empty()) {
76 auto sumSpectraAlg = factory.
create(
"SumSpectra");
77 sumSpectraAlg->setChild(
true);
78 sumSpectraAlg->initialize();
79 sumSpectraAlg->setProperty(
"InputWorkspace", inputWS);
80 sumSpectraAlg->setProperty(
"ListOfWorkspaceIndices", m_indexes);
81 sumSpectraAlg->setPropertyValue(
"OutputWorkspace",
"outWS");
82 sumSpectraAlg->execute();
83 outWS = sumSpectraAlg->getProperty(
"OutputWorkspace");
92class CropCommand :
public Command {
94 std::vector<int> m_indexes;
97 explicit CropCommand(std::vector<int> indexes) : m_indexes(
std::move(indexes)) {}
102 for (
size_t i = 0; i < m_indexes.size(); ++i) {
104 auto cropWorkspaceAlg = factory.
create(
"CropWorkspace");
105 cropWorkspaceAlg->setChild(
true);
106 cropWorkspaceAlg->initialize();
107 cropWorkspaceAlg->setProperty(
"InputWorkspace", inputWS);
108 cropWorkspaceAlg->setProperty(
"StartWorkspaceIndex", m_indexes[i]);
109 cropWorkspaceAlg->setProperty(
"EndWorkspaceIndex", m_indexes[i]);
110 cropWorkspaceAlg->setPropertyValue(
"OutputWorkspace",
"outWS");
111 cropWorkspaceAlg->execute();
116 auto conjoinWorkspaceAlg = factory.
create(
"ConjoinWorkspaces");
117 conjoinWorkspaceAlg->setChild(
true);
118 conjoinWorkspaceAlg->initialize();
119 conjoinWorkspaceAlg->setProperty(
"InputWorkspace1", outWS);
120 conjoinWorkspaceAlg->setProperty(
"InputWorkspace2", subRange);
121 conjoinWorkspaceAlg->execute();
122 outWS = conjoinWorkspaceAlg->getProperty(
"InputWorkspace1");
134 virtual Command *
interpret(
const std::string &instruction)
const = 0;
136 virtual ~CommandParser() =
default;
140using VecCommandParsers = std::vector<std::shared_ptr<CommandParser>>;
145template <
typename ProductType>
class CommandParserBase :
public CommandParser {
147 Command *
interpret(
const std::string &instruction)
const override {
148 Command *command =
nullptr;
149 boost::regex ex = getRegex();
150 if (boost::regex_match(instruction, ex)) {
152 command =
new ProductType(indexes);
154 command =
new NullCommand;
160 virtual std::string getSeparator()
const = 0;
161 virtual boost::regex getRegex()
const = 0;
167class AdditionParserRange :
public CommandParserBase<AdditionCommand> {
170 boost::regex getRegex()
const override {
171 static const boost::regex r(R
"(^\s*[0-9]+\s*\-\s*[0-9]+\s*$)");
174 std::string getSeparator()
const override {
return "-"; }
180class AdditionParser :
public CommandParser {
182 Command *
interpret(
const std::string &instruction)
const override {
183 Command *command =
nullptr;
184 static const boost::regex ex(R
"(^\s*[0-9]+\s*\+\s*[0-9]+\s*$)");
185 if (boost::regex_match(instruction, ex)) {
186 std::vector<std::string> arguments;
187 boost::split(arguments, instruction, boost::is_any_of(
"+"));
190 Mantid::Kernel::Strings::convert<int>(arguments.front(), minIndex);
191 Mantid::Kernel::Strings::convert<int>(arguments.back(), maxIndex);
192 std::vector<int> indexes;
193 indexes.emplace_back(minIndex);
194 indexes.emplace_back(maxIndex);
195 command =
new AdditionCommand(indexes);
197 command =
new NullCommand;
206class CropParserRange :
public CommandParserBase<CropCommand> {
209 boost::regex getRegex()
const override {
210 static const boost::regex r(R
"(^\s*[0-9]+\s*:\s*[0-9]+\s*$)");
213 std::string getSeparator()
const override {
return ":"; }
219class CropParserIndex :
public CommandParser {
221 Command *
interpret(
const std::string &instruction)
const override {
222 Command *command =
nullptr;
223 static const boost::regex ex(
"^\\s*[0-9]+\\s*$");
224 if (boost::regex_match(instruction, ex)) {
226 Mantid::Kernel::Strings::convert<int>(instruction,
index);
227 std::vector<int> indexes(1,
index);
228 command =
new CropCommand(indexes);
230 command =
new NullCommand;
259 "Input to processes workspace.");
261 "Processing instructions. See full instruction list.");
263 "Output processed workspace");
274VecCommands
interpret(
const std::string &processingInstructions) {
275 std::vector<std::string> processingInstructionsSplit;
276 boost::split(processingInstructionsSplit, processingInstructions, boost::is_any_of(
","));
278 VecCommandParsers commandParsers{std::make_shared<AdditionParserRange>(), std::make_shared<CropParserRange>(),
279 std::make_shared<CropParserIndex>(), std::make_shared<AdditionParser>()};
281 VecCommands commands;
282 for (
const auto &candidate : processingInstructionsSplit) {
283 bool parserFound =
false;
284 for (
const auto &commandParser : commandParsers) {
285 Command *command = commandParser->interpret(candidate);
286 std::shared_ptr<Command> commandSptr(command);
287 if (commandSptr->isValid())
290 commands.emplace_back(commandSptr);
294 throw std::invalid_argument(
"Cannot interpret " + candidate);
305 const std::string processingInstructions = this->
getProperty(
"ProcessingInstructions");
307 boost::regex re(R
"(^\s*[0-9]+\s*$|^(\s*,*[0-9]+(\s*(,|:|\+|\-)\s*)*[0-9]*)*$)");
308 if (!boost::regex_match(processingInstructions, re)) {
309 throw std::invalid_argument(
"ProcessingInstructions are not well formed: " + processingInstructions);
312 if (processingInstructions.empty()) {
314 cloneWS->initialize();
315 cloneWS->setProperty(
"InputWorkspace", inputWorkspace);
319 this->setProperty(
"OutputWorkspace", outWS);
322 VecCommands commands =
interpret(processingInstructions);
325 auto command = commands[0];
327 for (
size_t j = 1; j < commands.size(); ++j) {
328 outWS = commands[j]->executeAndAppend(inputWorkspace, outWS);
331 this->setProperty(
"OutputWorkspace", outWS);
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
The AlgorithmManagerImpl class is responsible for controlling algorithm instances.
IAlgorithm_sptr create(const std::string &algName, const int &version=-1)
Creates a managed algorithm with the option of choosing a version.
std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1) override
Create a Child Algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
A property class for workspaces.
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< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
VecCommands interpret(const std::string &processingInstructions)
Interpret the instructions as an ordered list of commands that can be executed later.
MANTID_KERNEL_DLL std::vector< int > parseRange(const std::string &str, const std::string &elemSep=",", const std::string &rangeSep="-")
Parses a number range, e.g.
@ Input
An input workspace.
@ Output
An output workspace.