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