-
Notifications
You must be signed in to change notification settings - Fork 122
/
CloneMDWorkspace.cpp
121 lines (107 loc) · 4.9 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
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidMDAlgorithms/CloneMDWorkspace.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidDataObjects/MDHistoWorkspace.h"
#include "MantidKernel/System.h"
#include <Poco/File.h>
#include <Poco/Path.h>
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
namespace Mantid::MDAlgorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CloneMDWorkspace)
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CloneMDWorkspace::init() {
declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("InputWorkspace", "", Direction::Input),
"An input MDEventWorkspace/MDHistoWorkspace.");
declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("OutputWorkspace", "", Direction::Output),
"Name of the output MDEventWorkspace/MDHistoWorkspace.");
std::vector<std::string> exts(1, ".nxs");
declareProperty(std::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) {
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. \n";
auto 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
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 << '\n';
Poco::File(originalFile).copyTo(outFilename);
g_log.information() << "File copied successfully.\n";
// Now load it back
auto 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", std::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 = std::dynamic_pointer_cast<IMDEventWorkspace>(inBaseWS);
MDHistoWorkspace_sptr inHistoWS = std::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::MDAlgorithms