Mantid
Loading...
Searching...
No Matches
RenameWorkspace.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 +
14
15namespace Mantid::Algorithms {
16
17// Register the class into the algorithm factory
18DECLARE_ALGORITHM(RenameWorkspace)
19
20using namespace Kernel;
21using namespace API;
22
27 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input));
28 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputWorkspace", "", Direction::Output));
29 declareProperty<bool>("RenameMonitors", false,
30 "If true, and monitor workspace found attached"
31 " to the source workspace, the monitors workspace is renamed too.\n"
32 "The monitor workspace name is created from the new workspace "
33 "name: NewWSName by adding the _monitors suffix"
34 " (e.g.: NewWSName_monitors)",
36 // Set to default true to maintain compatibility with existing scripts
37 // as this just allowed overriding by default
38 declareProperty<bool>("OverwriteExisting", true,
39 "If true any existing workspaces with the output name will be"
40 " overwritten. Defaults to true to maintain backwards compatibility.",
42}
43
49std::map<std::string, std::string> RenameWorkspace::validateInputs() {
50 using namespace std;
51 map<string, string> errorList;
52
53 // get the output workspace name
54 std::string outputwsName = getPropertyValue("OutputWorkspace");
55 // check if we are overriding existing workspaces
56 bool overrideWorkspaces = getProperty("OverwriteExisting");
57
58 // First check input and output names are different
59 if (getPropertyValue("InputWorkspace") == getPropertyValue("OutputWorkspace")) {
60 errorList["InputWorkspace"] = "Input and output workspace"
61 " names must be different";
62 errorList["OutputWorkspace"] = "Input and output workspace"
63 " names must be different";
64 }
65
66 // Test to see if the output already exists
67 if (AnalysisDataService::Instance().doesExist(outputwsName)) {
68 // Output name already exists - either remove or error
69 if (!overrideWorkspaces) {
70 // If we try to delete the workspace here a subtle bug is introduced
71 // Where the workspace group handle is deleted if we are renaming
72 // Its last workspace member, then when we add (or rename) that member
73 // undefined behavior happens usually Python Unit tests breaking
74 errorList["OutputWorkspace"] = "The workspace " + outputwsName + " already exists";
75 errorList["OverwriteExisting"] = "Set OverwriteExisting to true"
76 " to overwrite the existing workspace";
77 }
78 }
79
80 return errorList;
81}
82
89
90 // Get the input workspace
91 Workspace_sptr inputWS = getProperty("InputWorkspace");
92
93 WorkspaceGroup_sptr inputGroup = std::dynamic_pointer_cast<WorkspaceGroup>(inputWS);
94
95 // get the workspace name
96 std::string inputwsName = inputWS->getName();
97 // get the output workspace name
98 std::string outputwsName = getPropertyValue("OutputWorkspace");
99
100 // Assign it to the output workspace property
101 setProperty("OutputWorkspace", inputWS);
102
103 // rename the input workspace using the rename method
104 ADS.rename(inputwsName, outputwsName);
105
106 const bool renameMonitors = getProperty("RenameMonitors");
107 if (!renameMonitors)
108 return;
109
110 // Deal with attached monitor workspace if any.
111 auto matInputWS = std::dynamic_pointer_cast<MatrixWorkspace>(inputWS);
112 if (!matInputWS) // its some kind workspaces which may not have possibility
113 return; // to attach monitors to it
114 auto monWS = matInputWS->monitorWorkspace();
115 if (monWS) {
116 std::string monWSName = monWS->getName();
117 // rename the monitor workspace accordingly
118 if (monWSName.empty()) {
119 // workspace will always have name after added to ADS, so apparently not
120 // the case
121 ADS.add(outputwsName + "_monitors", monWS);
122 } else {
123 try {
124 ADS.rename(monWSName, outputwsName + "_monitors");
125 } catch (Kernel::Exception::NotFoundError &) { // it may be deleted
126 ADS.add(monWSName, monWS);
127 ADS.rename(monWSName, outputwsName + "_monitors");
128 }
129 }
130 }
131}
132
134 // Get the input & output workspace names
135 Workspace_sptr inputWS = getProperty("InputWorkspace");
136 const std::string inputwsName = inputWS->getName();
137 std::string outputwsName = getPropertyValue("OutputWorkspace");
138
139 if (inputwsName == outputwsName) {
140 throw std::invalid_argument("The input and output workspace names must be different");
141 }
142
143 // Cast the input to a group
144 WorkspaceGroup_sptr inputGroup = std::dynamic_pointer_cast<WorkspaceGroup>(inputWS);
145 assert(inputGroup); // Should always be true
146
147 // Decide whether we will rename the group members. Must do this before
148 // renaming group itself.
149 // Basically we rename if the members ALL follow the pattern GroupName_1, _2,
150 // _3 etc.
151 const bool renameMembers = inputGroup->areNamesSimilar();
152
153 AnalysisDataService::Instance().rename(inputwsName, outputwsName);
154
155 // If necessary, go through group members calling the algorithm on each one
156 if (renameMembers) {
157 const std::vector<std::string> names = inputGroup->getNames();
158
159 // loop over input ws group members
160 for (size_t i = 0; i < names.size(); ++i) {
161 try {
162 // new name of the member workspaces
163 std::stringstream suffix;
164 suffix << i + 1;
165 std::string wsName = outputwsName + "_" + suffix.str();
166
167 auto alg = API::AlgorithmManager::Instance().createUnmanaged(this->name(), this->version());
168 alg->initialize();
169 alg->setPropertyValue("InputWorkspace", names[i]);
170 alg->setPropertyValue("OutputWorkspace", wsName);
171 alg->setChild(true);
172 alg->enableHistoryRecordingForChild(false);
173 alg->execute();
175 // Will wind up here if group has somehow got messed up and a member
176 // doesn't exist. Should't be possible!
177 g_log.error() << ex.what() << '\n';
178 }
179 }
180 }
181
182 setProperty("OutputWorkspace", inputGroup);
183
184 // We finished successfully.
185 g_log.notice() << name() << " successful\n";
186
187 return true;
188}
189
190} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
A property class for workspaces.
std::map< std::string, std::string > validateInputs() override
Check that input params are valid.
void init() override
Initialisation method.
bool processGroups() override
Process WorkspaceGroup inputs.
void exec() override
Executes the algorithm.
int version() const override
Algorithm's version for identification overriding a virtual method.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
Exception for when an item is not found in a collection.
Definition: Exception.h:145
const char * what() const noexcept override
Writes out the range and limits.
Definition: Exception.cpp:105
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
STL namespace.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54