/
RenameWorkspace.cpp
191 lines (166 loc) · 6.93 KB
/
RenameWorkspace.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/RenameWorkspace.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidKernel/Exception.h"
#include "MantidAPI/AnalysisDataService.h"
namespace Mantid {
namespace Algorithms {
// Register the class into the algorithm factory
DECLARE_ALGORITHM(RenameWorkspace)
using namespace Kernel;
using namespace API;
/** Initialisation method.
*
*/
void RenameWorkspace::init() {
declareProperty(make_unique<WorkspaceProperty<Workspace>>(
"InputWorkspace", "", Direction::Input));
declareProperty(make_unique<WorkspaceProperty<Workspace>>(
"OutputWorkspace", "", Direction::Output));
declareProperty<bool>(
"RenameMonitors", false,
"If true, and monitor workspace found attached"
" to the source workspace, the monitors workspace is renamed too.\n"
"The monitor workspace name is created from the new workspace "
"name: NewWSName by adding the _monitors suffix"
" (e.g.: NewWSName_monitors)",
Direction::Input);
// Set to default true to maintain compatibility with existing scripts
// as this just allowed overriding by default
declareProperty<bool>(
"OverwriteExisting", true,
"If true any existing workspaces with the output name will be"
" overwritten. Defaults to true to maintain backwards compatibility.",
Direction::Input);
}
/**
* Tests that the inputs are all valid
* @return A map containing the incorrect workspace
* properties and an error message
*/
std::map<std::string, std::string> RenameWorkspace::validateInputs() {
using namespace std;
map<string, string> errorList;
// Get the input workspace
Workspace_sptr inputWS = getProperty("InputWorkspace");
// get the output workspace name
std::string outputwsName = getPropertyValue("OutputWorkspace");
// check if we are overriding existing workspaces
bool overrideWorkspaces = getProperty("OverwriteExisting");
// First check input and output names are different
if (getPropertyValue("InputWorkspace") ==
getPropertyValue("OutputWorkspace")) {
errorList["InputWorkspace"] = "Input and output workspace"
" names must be different";
errorList["OutputWorkspace"] = "Input and output workspace"
" names must be different";
}
// Test to see if the output already exists
if (AnalysisDataService::Instance().doesExist(outputwsName)) {
// Output name already exists - either remove or error
if (!overrideWorkspaces) {
// If we try to delete the workspace here a subtle bug is introduced
// Where the workspace group handle is deleted if we are renaming
// Its last workspace member, then when we add (or rename) that member
// undefined behavior happens usually Python Unit tests breaking
errorList["OutputWorkspace"] =
"The workspace " + outputwsName + " already exists";
errorList["OverwriteExisting"] = "Set OverwriteExisting to true"
" to overwrite the existing workspace";
}
}
return errorList;
}
/** Executes the algorithm
*
* @throw runtime_error Thrown if algorithm cannot execute
*/
void RenameWorkspace::exec() {
// Get the input workspace
Workspace_sptr inputWS = getProperty("InputWorkspace");
// get the workspace name
std::string inputwsName = inputWS->getName();
// get the output workspace name
std::string outputwsName = getPropertyValue("OutputWorkspace");
// Assign it to the output workspace property
setProperty("OutputWorkspace", inputWS);
// rename the input workspace using the rename method
AnalysisDataService::Instance().rename(inputwsName, outputwsName);
const bool renameMonitors = getProperty("RenameMonitors");
if (!renameMonitors)
return;
// Deal with attached monitor workspace if any.
auto matInputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(inputWS);
if (!matInputWS) // its some kind workspaces which may not have possibility
return; // to attach monitors to it
auto monWS = matInputWS->monitorWorkspace();
if (monWS) {
std::string monWSName = monWS->getName();
// rename the monitor workspace accordingly
if (monWSName.size() == 0) {
// workspace will always have name after added to ADS, so apparently not
// the case
AnalysisDataService::Instance().add(outputwsName + "_monitors", monWS);
} else {
try {
AnalysisDataService::Instance().rename(monWSName,
outputwsName + "_monitors");
} catch (Kernel::Exception::NotFoundError &) { // it may be deleted
AnalysisDataService::Instance().add(monWSName, monWS);
AnalysisDataService::Instance().rename(monWSName,
outputwsName + "_monitors");
}
}
}
}
bool RenameWorkspace::processGroups() {
// Get the input & output workspace names
Workspace_sptr inputWS = getProperty("InputWorkspace");
const std::string inputwsName = inputWS->name();
std::string outputwsName = getPropertyValue("OutputWorkspace");
if (inputwsName == outputwsName) {
throw std::invalid_argument(
"The input and output workspace names must be different");
}
// Cast the input to a group
WorkspaceGroup_sptr inputGroup =
boost::dynamic_pointer_cast<WorkspaceGroup>(inputWS);
assert(inputGroup); // Should always be true
// Decide whether we will rename the group members. Must do this before
// renaming group itself.
// Basically we rename if the members ALL follow the pattern GroupName_1, _2,
// _3 etc.
const bool renameMembers = inputGroup->areNamesSimilar();
AnalysisDataService::Instance().rename(inputwsName, outputwsName);
// If necessary, go through group members calling the algorithm on each one
if (renameMembers) {
const std::vector<std::string> names = inputGroup->getNames();
// loop over input ws group members
for (size_t i = 0; i < names.size(); ++i) {
try {
// new name of the member workspaces
std::stringstream suffix;
suffix << i + 1;
std::string wsName = outputwsName + "_" + suffix.str();
IAlgorithm *alg = API::FrameworkManager::Instance().createAlgorithm(
this->name(), this->version());
alg->setPropertyValue("InputWorkspace", names[i]);
alg->setPropertyValue("OutputWorkspace", wsName);
alg->execute();
} catch (Kernel::Exception::NotFoundError &ex) {
// Will wind up here if group has somehow got messed up and a member
// doesn't exist. Should't be possible!
g_log.error() << ex.what() << '\n';
}
}
}
setProperty("OutputWorkspace", inputWS);
// We finished successfully.
g_log.notice() << name() << " successful\n";
return true;
}
} // namespace Algorithms
} // namespace Mantid