Skip to content

Commit

Permalink
Refs #4894: SaveMD basic MDHistoWorkspace saving.
Browse files Browse the repository at this point in the history
  • Loading branch information
Janik Zikovsky committed May 14, 2012
1 parent 018d158 commit 73d897d
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ namespace MDEvents
return m_numEvents;
}

/** @return the direct pointer to the array of mask bits (bool). For speed/testing */
bool * getMaskArray()
{
return m_masks;
}

void setTo(signal_t signal, signal_t errorSquared, signal_t numEvents);

void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t errorSquared);
Expand Down
5 changes: 4 additions & 1 deletion Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/SaveMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ namespace MDEvents

/// Helper method
template<typename MDE, size_t nd>
void doSave(typename MDEventWorkspace<MDE, nd>::sptr ws);
void doSaveEvents(typename MDEventWorkspace<MDE, nd>::sptr ws);

/// Save the MDHistoWorkspace.
void doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws);

};

Expand Down
101 changes: 94 additions & 7 deletions Code/Mantid/Framework/MDEvents/src/SaveMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ If you specify UpdateFileBackEnd, then any changes (e.g. events added using the
#include "MantidAPI/Progress.h"
#include "MantidKernel/EnabledWhenProperty.h"
#include <Poco/File.h>
#include "MantidMDEvents/MDHistoWorkspace.h"

using namespace Mantid::Kernel;
using namespace Mantid::API;
Expand Down Expand Up @@ -53,16 +54,16 @@ namespace MDEvents
/// Sets documentation strings for this algorithm
void SaveMD::initDocs()
{
this->setWikiSummary("Save a MDEventWorkspace to a .nxs file.");
this->setOptionalMessage("Save a MDEventWorkspace to a .nxs file.");
this->setWikiSummary("Save a MDEventWorkspace or MDHistoWorkspace to a .nxs file.");
this->setOptionalMessage("Save a MDEventWorkspace or MDHistoWorkspace to a .nxs file.");
}

//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void SaveMD::init()
{
declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace","",Direction::Input), "An input MDEventWorkspace.");
declareProperty(new WorkspaceProperty<IMDWorkspace>("InputWorkspace","",Direction::Input), "An input MDEventWorkspace or MDHistoWorkspace.");

std::vector<std::string> exts;
exts.push_back(".nxs");
Expand Down Expand Up @@ -90,7 +91,7 @@ namespace MDEvents
* @param ws :: MDEventWorkspace of the given type
*/
template<typename MDE, size_t nd>
void SaveMD::doSave(typename MDEventWorkspace<MDE, nd>::sptr ws)
void SaveMD::doSaveEvents(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
std::string filename = getPropertyValue("Filename");
bool update = getProperty("UpdateFileBackEnd");
Expand Down Expand Up @@ -433,15 +434,101 @@ namespace MDEvents
}


//----------------------------------------------------------------------------------------------
/** Save a MDHistoWorkspace to a .nxs file
*
* @param ws :: MDHistoWorkspace to save
*/
void SaveMD::doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws)
{
std::string filename = getPropertyValue("Filename");

// Erase the file if it exists
Poco::File oldFile(filename);
if (oldFile.exists())
oldFile.remove();

// Create a new file in HDF5 mode.
::NeXus::File * file;
file = new ::NeXus::File(filename, NXACC_CREATE5);

// The base entry. Named so as to distinguish from other workspace types.
file->makeGroup("MDHistoWorkspace", "NXentry", true);

// Save all the ExperimentInfos
for (uint16_t i=0; i < ws->getNumExperimentInfo(); i++)
{
ExperimentInfo_sptr ei = ws->getExperimentInfo(i);
std::string groupName = "experiment" + Strings::toString(i);
if (ei)
{
// Can't overwrite entries. Just add the new ones
file->makeGroup(groupName, "NXgroup", true);
file->putAttr("version", 1);
ei->saveExperimentInfoNexus(file);
file->closeGroup();
}
}

// Save each dimension, as their XML representation
for (size_t d=0; d<ws->getNumDims(); d++)
{
std::ostringstream mess;
mess << "dimension" << d;
file->putAttr( mess.str(), ws->getDimension(d)->toXMLString() );
}

// Check that the typedef has not been changed. The NeXus types would need changing if it does!
assert(sizeof(signal_t) == sizeof(double));

// Number of data points
int nPoints = static_cast<int>(ws->getNPoints());

file->makeData("signal", ::NeXus::FLOAT64, nPoints, true);
file->putData(ws->getSignalArray());
file->closeData();

file->makeData("errors_squared", ::NeXus::FLOAT64, nPoints, true);
file->putData(ws->getErrorSquaredArray());
file->closeData();

file->makeData("num_events", ::NeXus::FLOAT64, nPoints, true);
file->putData(ws->getNumEventsArray());
file->closeData();

file->makeData("mask", ::NeXus::INT8, nPoints, true);
file->putData(ws->getMaskArray());
file->closeData();


// TODO: Links to original workspace???

file->closeGroup();
file->close();

}


//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void SaveMD::exec()
{
IMDEventWorkspace_sptr ws = getProperty("InputWorkspace");
IMDWorkspace_sptr ws = getProperty("InputWorkspace");
IMDEventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<IMDEventWorkspace>(ws);
MDHistoWorkspace_sptr histoWS = boost::dynamic_pointer_cast<MDHistoWorkspace>(ws);

// Wrapper to cast to MDEventWorkspace then call the function
CALL_MDEVENT_FUNCTION(this->doSave, ws);
if (eventWS)
{
// Wrapper to cast to MDEventWorkspace then call the function
CALL_MDEVENT_FUNCTION(this->doSaveEvents, eventWS);
}
else if (histoWS)
{
this->doSaveHisto(histoWS);
}
else
throw std::runtime_error("SaveMD can only save MDEventWorkspaces and MDHistoWorkspaces.\nPlease use SaveNexus or another algorithm appropriate for this workspace type.");
}


Expand Down
27 changes: 27 additions & 0 deletions Code/Mantid/Framework/MDEvents/test/SaveMDTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,33 @@ class SaveMDTest : public CxxTest::TestSuite
}


/** Run SaveMD with the MDHistoWorkspace */
void doTestHisto(MDHistoWorkspace_sptr ws)
{
std::string filename = "SaveMDTestHisto.nxs";

SaveMD alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", ws) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", filename) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("UpdateFileBackEnd", true) );
alg.execute();
TS_ASSERT( alg.isExecuted() );

filename = alg.getPropertyValue("Filename");
TSM_ASSERT( "File was indeed created", Poco::File(filename).exists());
// if (Poco::File(filename).exists())
// Poco::File(filename).remove();
}

void test_histo2()
{
MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.5, 2, 10, 10.0, 3.5, "histo2", 4.5);
doTestHisto(ws);
}


};


Expand Down

0 comments on commit 73d897d

Please sign in to comment.