/
CloneMDWorkspace.cpp
143 lines (126 loc) · 5.23 KB
/
CloneMDWorkspace.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
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidKernel/System.h"
#include "MantidDataObjects/MDEventFactory.h"
#include <Poco/File.h>
#include <Poco/Path.h>
#include "MantidAPI/FileProperty.h"
#include "MantidDataObjects/MDHistoWorkspace.h"
#include "MantidMDAlgorithms/CloneMDWorkspace.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
namespace Mantid {
namespace MDAlgorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CloneMDWorkspace)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
CloneMDWorkspace::CloneMDWorkspace() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
CloneMDWorkspace::~CloneMDWorkspace() {}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CloneMDWorkspace::init() {
declareProperty(make_unique<WorkspaceProperty<IMDWorkspace>>(
"InputWorkspace", "", Direction::Input),
"An input MDEventWorkspace/MDHistoWorkspace.");
declareProperty(make_unique<WorkspaceProperty<IMDWorkspace>>(
"OutputWorkspace", "", Direction::Output),
"Name of the output MDEventWorkspace/MDHistoWorkspace.");
std::vector<std::string> exts(1, ".nxs");
declareProperty(
Kernel::make_unique<FileProperty>("Filename", "",
FileProperty::OptionalSave, exts),
"If the input workspace is file-backed, specify a file to which to save "
"the cloned workspace.\n"
"If the workspace is file-backed but this parameter is NOT specified, "
"then a new filename with '_clone' appended is created next to the "
"original file.\n"
"No effect if the input workspace is NOT file-backed.\n"
"");
}
//----------------------------------------------------------------------------------------------
/** Perform the cloning
*
* @param ws :: MDEventWorkspace to clone
*/
template <typename MDE, size_t nd>
void CloneMDWorkspace::doClone(
const typename MDEventWorkspace<MDE, nd>::sptr ws) {
Progress prog(this, 0.0, 10.0, 100);
BoxController_sptr bc = ws->getBoxController();
if (!bc)
throw std::runtime_error("Error with InputWorkspace: no BoxController!");
if (bc->isFileBacked()) {
if (ws->fileNeedsUpdating()) {
// Data was modified! You need to save first.
g_log.notice() << "InputWorkspace's file-backend being updated. "
<< std::endl;
IAlgorithm_sptr alg = createChildAlgorithm("SaveMD", 0.0, 0.4, false);
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("UpdateFileBackEnd", "1");
alg->executeAsChildAlg();
}
// Generate a new filename to copy to
prog.report("Copying File");
std::string originalFile = bc->getFilename();
std::string outFilename = getPropertyValue("Filename");
if (outFilename.empty()) {
// Auto-generated name
Poco::Path path = Poco::Path(originalFile).absolute();
std::string newName =
path.getBaseName() + "_clone." + path.getExtension();
path.setFileName(newName);
outFilename = path.toString();
}
// Perform the copying
g_log.notice() << "Cloned workspace file being copied to: " << outFilename
<< std::endl;
Poco::File(originalFile).copyTo(outFilename);
g_log.information() << "File copied successfully." << std::endl;
// Now load it back
IAlgorithm_sptr alg = createChildAlgorithm("LoadMD", 0.5, 1.0, false);
alg->setPropertyValue("Filename", outFilename);
alg->setPropertyValue("FileBackEnd", "1");
alg->setPropertyValue("Memory", "0"); // TODO: How much memory?
alg->executeAsChildAlg();
// Set the output workspace to this
IMDWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
this->setProperty("OutputWorkspace",
boost::dynamic_pointer_cast<IMDWorkspace>(outWS));
} else {
// Perform the clone in memory.
IMDWorkspace_sptr outWS(ws->clone());
setProperty("OutputWorkspace", outWS);
}
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void CloneMDWorkspace::exec() {
IMDWorkspace_sptr inBaseWS = getProperty("InputWorkspace");
IMDEventWorkspace_sptr inWS =
boost::dynamic_pointer_cast<IMDEventWorkspace>(inBaseWS);
MDHistoWorkspace_sptr inHistoWS =
boost::dynamic_pointer_cast<MDHistoWorkspace>(inBaseWS);
if (inWS) {
CALL_MDEVENT_FUNCTION(this->doClone, inWS);
} else if (inHistoWS) {
// Polymorphic clone().
IMDWorkspace_sptr outWS(inHistoWS->clone());
// And set to the output. Easy.
this->setProperty("OutputWorkspace", outWS);
} else {
// Call CloneWorkspace as a fall-back?
throw std::runtime_error("CloneMDWorkspace can only clone a "
"MDEventWorkspace or MDHistoWorkspace. Try "
"CloneWorkspace.");
}
}
} // namespace Mantid
} // namespace DataObjects