Mantid
Loading...
Searching...
No Matches
CloneMDWorkspace.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 <Poco/File.h>
13#include <Poco/Path.h>
14
15using namespace Mantid::Kernel;
16using namespace Mantid::API;
17using namespace Mantid::DataObjects;
18
19namespace Mantid::MDAlgorithms {
20
21// Register the algorithm into the AlgorithmFactory
22DECLARE_ALGORITHM(CloneMDWorkspace)
23
24//----------------------------------------------------------------------------------------------
27void CloneMDWorkspace::init() {
28 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("InputWorkspace", "", Direction::Input),
29 "An input MDEventWorkspace/MDHistoWorkspace.");
30 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("OutputWorkspace", "", Direction::Output),
31 "Name of the output MDEventWorkspace/MDHistoWorkspace.");
32
33 std::vector<std::string> exts(1, ".nxs");
34 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::OptionalSave, exts),
35 "If the input workspace is file-backed, specify a file to which to save "
36 "the cloned workspace.\n"
37 "If the workspace is file-backed but this parameter is NOT specified, "
38 "then a new filename with '_clone' appended is created next to the "
39 "original file.\n"
40 "No effect if the input workspace is NOT file-backed.\n"
41 "");
42}
43
44//----------------------------------------------------------------------------------------------
45
50template <typename MDE, size_t nd> void CloneMDWorkspace::doClone(const typename MDEventWorkspace<MDE, nd>::sptr &ws) {
52
53 if (!bc)
54 throw std::runtime_error("Error with InputWorkspace: no BoxController!");
55 if (bc->isFileBacked()) {
56 if (ws->fileNeedsUpdating()) {
57 // Data was modified! You need to save first.
58 g_log.notice() << "InputWorkspace's file-backend being updated. \n";
59 auto alg = createChildAlgorithm("SaveMD", 0.0, 0.4, false);
60 alg->setProperty("InputWorkspace", ws);
61 alg->setProperty("UpdateFileBackEnd", true);
62 alg->executeAsChildAlg();
63 }
64
65 // Generate a new filename to copy to
66 std::string originalFile = bc->getFilename();
67 std::string outFilename = getPropertyValue("Filename");
68 if (outFilename.empty()) {
69 // Auto-generated name
70 Poco::Path path = Poco::Path(originalFile).absolute();
71 std::string newName = path.getBaseName() + "_clone." + path.getExtension();
72 path.setFileName(newName);
73 outFilename = path.toString();
74 }
75
76 // Perform the copying. HDF5 takes a file lock out when opening the file. On Windows this
77 // prevents the a read handle being opened to perform the clone so we need to close the
78 // file, do the copy, then reopen it on the original box controller
79 g_log.notice() << "Cloned workspace file being copied to: " << outFilename << '\n';
80 bc->getFileIO()->copyFileTo(outFilename);
81 g_log.information() << "File copied successfully.\n";
82
83 // Now load it back
84 auto alg = createChildAlgorithm("LoadMD", 0.5, 1.0, false);
85 alg->setPropertyValue("Filename", outFilename);
86 alg->setPropertyValue("FileBackEnd", "1");
87 alg->setPropertyValue("Memory", "0"); // TODO: How much memory?
88 alg->executeAsChildAlg();
89
90 // Set the output workspace to this
91 IMDWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
92 this->setProperty("OutputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(outWS));
93 } else {
94 // Perform the clone in memory.
95 IMDWorkspace_sptr outWS(ws->clone());
96 setProperty("OutputWorkspace", outWS);
97 }
98}
99
100//----------------------------------------------------------------------------------------------
104 IMDWorkspace_sptr inBaseWS = getProperty("InputWorkspace");
105 IMDEventWorkspace_sptr inWS = std::dynamic_pointer_cast<IMDEventWorkspace>(inBaseWS);
106 MDHistoWorkspace_sptr inHistoWS = std::dynamic_pointer_cast<MDHistoWorkspace>(inBaseWS);
107
108 if (inWS) {
109 CALL_MDEVENT_FUNCTION(this->doClone, inWS);
110 } else if (inHistoWS) {
111 // Polymorphic clone().
112 IMDWorkspace_sptr outWS(inHistoWS->clone());
113 // And set to the output. Easy.
114 this->setProperty("OutputWorkspace", outWS);
115 } else {
116 // Call CloneWorkspace as a fall-back?
117 throw std::runtime_error("CloneMDWorkspace can only clone a "
118 "MDEventWorkspace or MDHistoWorkspace. Try "
119 "CloneWorkspace.");
120 }
121}
122
123} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ OptionalSave
to specify a file to write to but an empty string is
A property class for workspaces.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
std::unique_ptr< MDEventWorkspace > clone() const
Returns a clone of the workspace.
Mantid::API::BoxController_sptr getBoxController() override
Returns the BoxController used in this workspace.
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:126
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
Algorithm to clone a MDEventWorkspace to a new one.
void exec() override
Run the algorithm.
void doClone(const typename DataObjects::MDEventWorkspace< MDE, nd >::sptr &ws)
Perform the cloning.
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54