Commit e053866e authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony
Browse files

Load and save the MD coordinate system

Backwards compatability is preserved by checking for the log as it would have existed.
Refs #11359
parent 181db647
......@@ -75,6 +75,8 @@ private:
void loadDimensions();
void loadCoordinateSystem();
/// Load all the affine matricies
void loadAffineMatricies(API::IMDWorkspace_sptr ws);
/// Load a given affine matrix
......@@ -91,6 +93,8 @@ private:
/// Each dimension object loaded.
std::vector<Mantid::Geometry::IMDDimension_sptr> m_dims;
/// Coordinate system
Kernel::SpecialCoordinateSystem m_coordSystem;
/// load only the box structure with empty boxes but do not tload boxes events
bool m_BoxStructureAndMethadata;
};
......
......@@ -40,7 +40,8 @@ DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMD);
/** Constructor
*/
LoadMD::LoadMD()
: m_numDims(0), // uninitialized incorrect value
: m_numDims(0), // uninitialized incorrect value
m_coordSystem(None),
m_BoxStructureAndMethadata(true) // this is faster but rarely needed.
{}
......@@ -168,6 +169,8 @@ void LoadMD::exec() {
// Now load all the dimension xml
this->loadDimensions();
// Coordinate system
this->loadCoordinateSystem();
if (entryName == "MDEventWorkspace") {
// The type of event
......@@ -233,6 +236,9 @@ void LoadMD::loadHisto() {
// Now the ExperimentInfo
MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws);
// Coordinate system
ws->setCoordinateSystem(m_coordSystem);
// Load the WorkspaceHistory "process"
ws->history().loadNexus(m_file.get());
......@@ -267,6 +273,30 @@ void LoadMD::loadDimensions() {
}
}
/** Load the coordinate system **/
void LoadMD::loadCoordinateSystem() {
// Current version stores the coordinate system
// in its own field. The first version stored it
// as a log value so fallback on that if it can't
// be found.
try {
uint32_t readCoord(0);
m_file->readData("coordinate_system", readCoord);
m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
} catch (::NeXus::Exception &) {
auto pathOnEntry = m_file->getPath();
try {
m_file->openPath(pathOnEntry + "/experiment0/logs/CoordinateSystem");
int readCoord(0);
m_file->readData("value", readCoord);
m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
} catch (::NeXus::Exception &) {
}
// return to where we started
m_file->openPath(pathOnEntry);
}
}
//----------------------------------------------------------------------------------------------
/** Do the loading.
*
......@@ -302,6 +332,9 @@ void LoadMD::doLoad(typename MDEventWorkspace<MDE, nd>::sptr ws) {
for (size_t d = 0; d < nd; d++)
ws->addDimension(m_dims[d]);
// Coordinate system
ws->setCoordinateSystem(m_coordSystem);
// ----------------------------------------- Box Structure
// ------------------------------
prog->report("Reading box structure from HDD.");
......
......@@ -235,6 +235,10 @@ void SaveMD::doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws) {
// The base entry. Named so as to distinguish from other workspace types.
file->makeGroup("MDHistoWorkspace", "NXentry", true);
// Write out the coordinate system
file->writeData("coordinate_system",
static_cast<uint32_t>(ws->getSpecialCoordinateSystem()));
// Save the algorithm history under "process"
ws->getHistory().saveNexus(file);
......
......@@ -17,6 +17,8 @@
#include "MantidAPI/ExperimentInfo.h"
#include "MantidMDAlgorithms/LoadMD.h"
#include <hdf5.h>
using namespace Mantid;
using namespace Mantid::MDEvents;
using namespace Mantid::MDAlgorithms;
......@@ -531,44 +533,122 @@ public:
}
/// More of an integration test as it uses both load and save.
void test_save_and_load_special_coordinates()
{
MDEventWorkspace1Lean::sptr ws = MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
// Set the special coordinate system
void test_save_and_load_special_coordinates_MDEventWorkspace() {
MDEventWorkspace1Lean::sptr mdeventWS =
MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
mdeventWS->setCoordinateSystem(appliedCoordinateSystem);
auto loadedWS = testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace");
// Check that the special coordinate system is the same before the save-load
// cycle.
TS_ASSERT_EQUALS(appliedCoordinateSystem,
loadedWS->getSpecialCoordinateSystem());
}
// backwards-compatability check for coordinate in log
void test_load_coordinate_system_MDEventWorkspace_from_experiment_info() {
MDEventWorkspace1Lean::sptr mdeventWS =
MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
ws->setCoordinateSystem(appliedCoordinateSystem);
mdeventWS->setCoordinateSystem(appliedCoordinateSystem);
// Create a log in the first experiment info to simulated an old version of
// the file
auto expt0 = mdeventWS->getExperimentInfo(0);
expt0->mutableRun().addProperty("CoordinateSystem",
static_cast<int>(appliedCoordinateSystem));
const bool rmCoordField(true);
auto loadedWS =
testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace", rmCoordField);
// Check that the special coordinate system is the same before the save-load
// cycle.
TS_ASSERT_EQUALS(appliedCoordinateSystem,
loadedWS->getSpecialCoordinateSystem());
}
const std::string inputWSName = "SaveMDSpecialCoordinatesTest";
const std::string fileName = inputWSName + ".nxs";
AnalysisDataService::Instance().addOrReplace(inputWSName, ws);
void test_save_and_load_special_coordinates_MDHistoWorkspace() {
auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace(
2.5, 2, 10, 10.0, 3.5, "", 4.5);
const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
mdhistoWS->setCoordinateSystem(appliedCoordinateSystem);
auto loadedWS = testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace");
// Check that the special coordinate system is the same before the save-load
// cycle.
TS_ASSERT_EQUALS(appliedCoordinateSystem,
loadedWS->getSpecialCoordinateSystem());
}
// backwards-compatability check for coordinate in log
void test_load_coordinate_system_MDHistoWorkspace_from_experiment_info() {
auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace(
2.5, 2, 10, 10.0, 3.5, "", 4.5);
const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
mdhistoWS->setCoordinateSystem(appliedCoordinateSystem);
// Create a log in the first experiment info to simulated an old version of
// the file
auto expt0 = mdhistoWS->getExperimentInfo(0);
expt0->mutableRun().addProperty("CoordinateSystem",
static_cast<int>(appliedCoordinateSystem));
const bool rmCoordField(true);
auto loadedWS =
testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace", rmCoordField);
// Check that the special coordinate system is the same before the save-load
// cycle.
TS_ASSERT_EQUALS(appliedCoordinateSystem,
loadedWS->getSpecialCoordinateSystem());
}
Mantid::API::IMDWorkspace_sptr
testSaveAndLoadWorkspace(Mantid::API::IMDWorkspace_sptr inputWS,
const std::string &rootGroup,
const bool rmCoordField = false) {
const std::string fileName = "SaveMDSpecialCoordinatesTest.nxs";
SaveMD saveAlg;
saveAlg.setChild(true);
saveAlg.initialize();
saveAlg.isInitialized();
saveAlg.setPropertyValue("InputWorkspace", inputWSName);
saveAlg.setProperty("InputWorkspace", inputWS);
saveAlg.setPropertyValue("Filename", fileName);
saveAlg.execute();
TS_ASSERT( saveAlg.isExecuted() );
std::string this_fileName = saveAlg.getProperty("Filename");
if (rmCoordField) {
// Remove the coordinate_system entry so it falls back on the log. NeXus
// can't do this
// so use the HDF5 API directly
auto fid = H5Fopen(fileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
auto gid = H5Gopen(fid, rootGroup.c_str(), H5P_DEFAULT);
if (gid > 0) {
H5Ldelete(gid, "coordinate_system", H5P_DEFAULT);
H5Gclose(gid);
} else {
TS_FAIL("Cannot open MDEventWorkspace group. Test file has unexpected "
"structure.");
}
H5Fclose(fid);
}
LoadMD loadAlg;
loadAlg.setChild(true);
loadAlg.initialize();
loadAlg.isInitialized();
loadAlg.setPropertyValue("Filename", fileName);
loadAlg.setProperty("FileBackEnd", false);
loadAlg.setPropertyValue("OutputWorkspace", "reloaded_again");
loadAlg.setPropertyValue("OutputWorkspace", "_unused_for_child");
loadAlg.execute();
TS_ASSERT( loadAlg.isExecuted() );
// Check that the special coordinate system is the same before the save-load cycle.
TS_ASSERT_EQUALS(appliedCoordinateSystem, ws->getSpecialCoordinateSystem());
if (Poco::File(this_fileName).exists())
{
Poco::File(this_fileName).remove();
}
AnalysisDataService::Instance().remove(inputWSName);
AnalysisDataService::Instance().remove("OutputWorkspace");
return loadAlg.getProperty("OutputWorkspace");
}
void test_loadAffine()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment