Mantid
Loading...
Searching...
No Matches
GroupWorkspaces.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 +
12#include "MantidKernel/Glob.h"
13#include <regex>
14
15namespace Mantid::Algorithms {
16
17DECLARE_ALGORITHM(GroupWorkspaces)
18
19using namespace API;
20using namespace Kernel;
21
24
26 std::make_unique<ArrayProperty<std::string>>("InputWorkspaces", std::make_shared<ADSValidator>(true, true)),
27 "Names of the Input Workspaces to Group");
28 declareProperty(std::make_unique<PropertyWithValue<std::string>>("GlobExpression", ""),
29 "Add all Workspaces that match Glob expression to Group");
30 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>("OutputWorkspace", "", Direction::Output),
31 "Name of the workspace to be created as the output of grouping ");
32}
33
38 const std::vector<std::string> inputWorkspaces = getProperty("InputWorkspaces");
39
40 const std::string globExpression = getProperty("GlobExpression");
41 std::string outputWorkspace = getProperty("OutputWorkspace");
42
43 // Clear WorkspaceGroup in case algorithm instance is reused.
44 m_group = nullptr;
45
46 if (!inputWorkspaces.empty())
47 addToGroup(inputWorkspaces, outputWorkspace);
48 if (!globExpression.empty())
49 addToGroup(globExpression);
50 if ((m_group == nullptr) || m_group->isEmpty())
51 throw std::invalid_argument("Glob pattern " + globExpression + " does not match any workspace names in the ADS.");
52 setProperty("OutputWorkspace", m_group);
53 auto &notifier = API::AnalysisDataService::Instance().notificationCenter;
54 notifier.postNotification(new WorkspacesGroupedNotification(inputWorkspaces));
55}
56
57std::map<std::string, std::string> GroupWorkspaces::validateInputs() {
58 std::map<std::string, std::string> results;
59 const std::vector<std::string> inputWorkspaces = getProperty("InputWorkspaces");
60 std::string globExpression = getProperty("GlobExpression");
61
62 for (auto it = globExpression.begin(); it < globExpression.end(); ++it) {
63 if (*it == '\\') {
64 it = globExpression.erase(it, it + 1);
65 }
66 }
67
68 if (inputWorkspaces.empty() && globExpression.empty()) {
69 results["InputWorkspaces"] = "No InputWorkspace names specified. Rerun with a list of workspaces "
70 "names or a glob expression";
71 return results;
72 }
73
74 // ADSValidator already checks names in inputWorkspaces
75
76 if (!globExpression.empty()) {
77 // This is only a sanity check. If may fail to detect subtle errors in
78 // complex expressions.
79 if (globExpression.find_first_of("*?[]") == std::string::npos) {
80 results["GlobExpression"] = "Expression is expected to contain one or "
81 "more of the following characters: *?[";
82 return results;
83 }
84 if (std::count(globExpression.cbegin(), globExpression.cend(), '[') !=
85 std::count(globExpression.cbegin(), globExpression.cend(), ']')) {
86 results["GlobExpression"] = "Expression has a mismatched number of []";
87 return results;
88 }
89 }
90 return results;
91}
92
97void GroupWorkspaces::addToGroup(const std::string &globExpression) {
98 const std::string globRegexp = Kernel::Glob::globToRegex(globExpression);
99 g_log.debug() << "convert \"" << globExpression << "\" to \"" << globRegexp << "\"\n";
100 std::regex pattern(globRegexp);
101
102 const AnalysisDataServiceImpl &ads = AnalysisDataService::Instance();
103 const auto wsNames = ads.topLevelItems();
104 for (const auto &wsName : wsNames) {
105 if (std::regex_match(wsName.first, pattern)) {
106 addToGroup(wsName.second);
107 }
108 }
109}
110
116void GroupWorkspaces::addToGroup(const std::vector<std::string> &names, const std::string &outputName) {
117
118 AnalysisDataServiceImpl &ads = AnalysisDataService::Instance();
119 for (const auto &wsName : names) {
120 addToGroup(wsName != outputName ? ads.retrieve(wsName) : ads.remove(wsName));
121 }
122}
123
129 auto localGroup = std::dynamic_pointer_cast<WorkspaceGroup>(workspace);
130 auto &ads = AnalysisDataService::Instance();
131 if (localGroup) {
132 addToGroup(localGroup->getNames());
133 if (ads.doesExist(workspace->getName())) {
134 // Remove the group from the ADS
135 ads.remove(workspace->getName());
136 }
137 } else {
138 if (!m_group)
139 m_group = std::make_shared<WorkspaceGroup>();
140 m_group->addWorkspace(workspace);
141 }
142}
143} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
IPeaksWorkspace_sptr workspace
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
The Analysis data service stores instances of the Workspace objects and anything that derives from te...
std::map< std::string, Workspace_sptr > topLevelItems() const
Return a lookup of the top level items.
virtual Workspace_sptr remove(const std::string &name)
Overridden remove member to delete its name held by the workspace itself.
A property class for workspaces.
void init() override
Overridden Init method.
void addToGroup(const std::vector< std::string > &names, const std::string &outputName="")
Add a list of names to the new group.
void exec() override
overridden execute method
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
API::WorkspaceGroup_sptr m_group
A pointer to the new group.
Support for a property that holds an array of values.
std::shared_ptr< T > retrieve(const std::string &name) const
Get a shared pointer to a stored data object.
static std::string globToRegex(const std::string &globPattern)
Convert a glob pattern to an equivalent regular expression.
Definition Glob.cpp:51
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
The concrete, templated class for properties.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
AnalysisDataServiceImpl::GroupWorkspacesNotification WorkspacesGroupedNotification
@ Output
An output workspace.
Definition Property.h:54