Newer
Older
#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;
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
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(new WorkspaceProperty<IMDWorkspace>("InputWorkspace", "",
Direction::Input),
"An input MDEventWorkspace/MDHistoWorkspace.");
declareProperty(new WorkspaceProperty<IMDWorkspace>("OutputWorkspace", "",
Direction::Output),
"Name of the output MDEventWorkspace/MDHistoWorkspace.");
std::vector<std::string> exts(1, ".nxs");
declareProperty(
new 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");
}
// 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().release());
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().release());
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