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 <filesystem>
13
14using namespace Mantid::Kernel;
15using namespace Mantid::API;
16using namespace Mantid::DataObjects;
17
18namespace Mantid::MDAlgorithms {
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(CloneMDWorkspace)
22
23//----------------------------------------------------------------------------------------------
26void CloneMDWorkspace::init() {
27 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("InputWorkspace", "", Direction::Input),
28 "An input MDEventWorkspace/MDHistoWorkspace.");
29 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("OutputWorkspace", "", Direction::Output),
30 "Name of the output MDEventWorkspace/MDHistoWorkspace.");
31
32 std::vector<std::string> exts(1, ".nxs");
33 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::OptionalSave, exts),
34 "If the input workspace is file-backed, specify a file to which to save "
35 "the cloned workspace.\n"
36 "If the workspace is file-backed but this parameter is NOT specified, "
37 "then a new filename with '_clone' appended is created next to the "
38 "original file.\n"
39 "No effect if the input workspace is NOT file-backed.\n"
40 "");
41}
42
43//----------------------------------------------------------------------------------------------
44
49template <typename MDE, size_t nd> void CloneMDWorkspace::doClone(const typename MDEventWorkspace<MDE, nd>::sptr &ws) {
51
52 if (!bc)
53 throw std::runtime_error("Error with InputWorkspace: no BoxController!");
54 if (bc->isFileBacked()) {
55 if (ws->fileNeedsUpdating()) {
56 // Data was modified! You need to save first.
57 g_log.notice() << "InputWorkspace's file-backend being updated. \n";
58 auto alg = createChildAlgorithm("SaveMD", 0.0, 0.4, false);
59 alg->setProperty("InputWorkspace", ws);
60 alg->setProperty("UpdateFileBackEnd", true);
61 alg->executeAsChildAlg();
62 }
63
64 // Generate a new filename to copy to
65 std::string originalFile = bc->getFilename();
66 std::string outFilename = getPropertyValue("Filename");
67 if (outFilename.empty()) {
68 // Auto-generated name
69 std::filesystem::path path = std::filesystem::absolute(originalFile);
70 std::string newName = path.stem().string() + "_clone" + path.extension().string();
71 path.replace_filename(newName);
72 outFilename = path.string();
73 }
74
75 // Perform the copying. HDF5 takes a file lock out when opening the file. On Windows this
76 // prevents the a read handle being opened to perform the clone so we need to close the
77 // file, do the copy, then reopen it on the original box controller
78 g_log.notice() << "Cloned workspace file being copied to: " << outFilename << '\n';
79 bc->getFileIO()->copyFileTo(outFilename);
80 g_log.information() << "File copied successfully.\n";
81
82 // Now load it back
83 auto alg = createChildAlgorithm("LoadMD", 0.5, 1.0, false);
84 alg->setPropertyValue("Filename", outFilename);
85 alg->setPropertyValue("FileBackEnd", "1");
86 alg->setPropertyValue("Memory", "0"); // TODO: How much memory?
87 alg->executeAsChildAlg();
88
89 // Set the output workspace to this
90 IMDWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
91 this->setProperty("OutputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(outWS));
92 } else {
93 // Perform the clone in memory.
94 IMDWorkspace_sptr outWS(ws->clone());
95 setProperty("OutputWorkspace", outWS);
96 }
97}
98
99//----------------------------------------------------------------------------------------------
103 IMDWorkspace_sptr inBaseWS = getProperty("InputWorkspace");
104 IMDEventWorkspace_sptr inWS = std::dynamic_pointer_cast<IMDEventWorkspace>(inBaseWS);
105 MDHistoWorkspace_sptr inHistoWS = std::dynamic_pointer_cast<MDHistoWorkspace>(inBaseWS);
106
107 if (inWS) {
108 CALL_MDEVENT_FUNCTION(this->doClone, inWS);
109 } else if (inHistoWS) {
110 // Polymorphic clone().
111 IMDWorkspace_sptr outWS(inHistoWS->clone());
112 // And set to the output. Easy.
113 this->setProperty("OutputWorkspace", outWS);
114 } else {
115 // Call CloneWorkspace as a fall-back?
116 throw std::runtime_error("CloneMDWorkspace can only clone a "
117 "MDEventWorkspace or MDHistoWorkspace. Try "
118 "CloneWorkspace.");
119 }
120}
121
122} // 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