Skip to content

Commit

Permalink
refs #5979 test which shows errors without handling huge files
Browse files Browse the repository at this point in the history
  • Loading branch information
abuts committed Oct 30, 2012
1 parent e4d9038 commit 88b3b77
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidNexusCPP/NeXusFile.hpp"

namespace Mantid
{
Expand Down Expand Up @@ -48,6 +49,8 @@ namespace MDAlgorithms
/// Algorithm's category for identification
virtual const std::string category() const { return "MDAlgorithms";}

protected: // for testing
void saveExperimentInfos(::NeXus::File * const file, API::IMDEventWorkspace_const_sptr ws);
private:
/// Sets documentation strings for this algorithm
virtual void initDocs();
Expand Down
78 changes: 43 additions & 35 deletions Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ If you specify UpdateFileBackEnd, then any changes (e.g. events added using the
#include "MantidMDEvents/MDEventFactory.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDAlgorithms/SaveMD.h"
#include "MantidNexusCPP/NeXusFile.hpp"
#include "MantidMDEvents/MDBox.h"
#include "MantidAPI/Progress.h"
#include "MantidKernel/EnabledWhenProperty.h"
Expand Down Expand Up @@ -85,6 +84,48 @@ namespace MDAlgorithms
setPropertySettings("MakeFileBacked", new EnabledWhenProperty("UpdateFileBackEnd", IS_EQUAL_TO, "0"));
}

/// Save each NEW ExperimentInfo to a spot in the file
void SaveMD::saveExperimentInfos(::NeXus::File * const file, API::IMDEventWorkspace_const_sptr ws)
{

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

// Warning for high detector IDs.
// The routine in MDEvent::saveVectorToNexusSlab() converts detector IDs to single-precision floats
// Floats only have 24 bits of int precision = 16777216 as the max, precise detector ID
detid_t min = 0;
detid_t max = 0;
try
{
ei->getInstrument()->getMinMaxDetectorIDs(min, max);
}
catch (std::runtime_error &)
{ /* Ignore error. Min/max will be 0 */ }

if (max > 16777216)
{
g_log.warning() << "This instrument (" << ei->getInstrument()->getName() <<
") has detector IDs that are higher than can be saved in the .NXS file as single-precision floats." << std::endl;
g_log.warning() << "Detector IDs above 16777216 will not be precise. Please contact the developers." << std::endl;
}
}
}



}
//----------------------------------------------------------------------------------------------
/** Save the MDEventWorskpace to a file.
* Based on the Intermediate Data Format Detailed Design Document, v.1.R3 found in SVN.
Expand Down Expand Up @@ -154,40 +195,7 @@ namespace MDAlgorithms
}

// Save each NEW ExperimentInfo to a spot in the file
std::map<std::string,std::string> entries;
file->getEntries(entries);
for (uint16_t i=0; i < ws->getNumExperimentInfo(); i++)
{
ExperimentInfo_sptr ei = ws->getExperimentInfo(i);
std::string groupName = "experiment" + Strings::toString(i);
if (entries.find(groupName) == entries.end())
{
// Can't overwrite entries. Just add the new ones
file->makeGroup(groupName, "NXgroup", true);
file->putAttr("version", 1);
ei->saveExperimentInfoNexus(file);
file->closeGroup();

// Warning for high detector IDs.
// The routine in MDEvent::saveVectorToNexusSlab() converts detector IDs to single-precision floats
// Floats only have 24 bits of int precision = 16777216 as the max, precise detector ID
detid_t min = 0;
detid_t max = 0;
try
{
ei->getInstrument()->getMinMaxDetectorIDs(min, max);
}
catch (std::runtime_error &)
{ /* Ignore error. Min/max will be 0 */ }

if (max > 16777216)
{
g_log.warning() << "This instrument (" << ei->getInstrument()->getName() <<
") has detector IDs that are higher than can be saved in the .NXS file as single-precision floats." << std::endl;
g_log.warning() << "Detector IDs above 16777216 will not be precise. Please contact the developers." << std::endl;
}
}
}
this->saveExperimentInfos(file,ws);

// Save some info as attributes. (Note: need to use attributes, not data sets because those cannot be resized).
file->putAttr("definition", ws->id());
Expand Down
57 changes: 57 additions & 0 deletions Code/Mantid/Framework/MDAlgorithms/test/SaveMDTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,28 @@
#include "MantidMDAlgorithms/SaveMD.h"
#include "MantidTestHelpers/MDEventsTestHelper.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/IMDEventWorkspace.h"

#include <cxxtest/TestSuite.h>
#include <iomanip>
#include <iostream>
#include "MantidKernel/CPUTimer.h"
#include <Poco/File.h>


using namespace Mantid::MDEvents;
using namespace Mantid::MDAlgorithms;
using namespace Mantid::API;
using Mantid::Kernel::CPUTimer;

class SaveMDTester: public SaveMD
{
public:
void saveExperimentInfos(::NeXus::File * const file, IMDEventWorkspace_const_sptr ws)
{
this->saveExperimentInfos(file, ws);
}
};

/** Note: See the LoadMDTest class
* for a more thorough test that does
Expand Down Expand Up @@ -145,6 +156,51 @@ class SaveMDTest : public CxxTest::TestSuite
//if (Poco::File(fullPath).exists()) Poco::File(fullPath).remove();
}

void test_saveExpInfo()
{
std::string filename("MultiExperSaveTest.nxs");
// Make a 1D MDEventWorkspace
MDEventWorkspace1Lean::sptr ws = MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
// Make sure it is split
ws->splitBox();

Mantid::Geometry::Goniometer gon;
gon.pushAxis("Psi",0,1,0);
// add experiment infos
for(int i=0;i<80;i++)
{
ExperimentInfo_sptr ei = boost::shared_ptr<ExperimentInfo>(new ExperimentInfo());
ei->mutableRun().addProperty("Psi",double(i));
ei->mutableRun().addProperty("Ei",400.);
ei->mutableRun().setGoniometer(gon,true);
ws->addExperimentInfo(ei);
}

AnalysisDataService::Instance().addOrReplace("SaveMDTest_ws", ws);

ws->refreshCache();

// There are this many boxes, so this is the max ID.
TS_ASSERT_EQUALS( ws->getBoxController()->getMaxId(), 11);

IMDEventWorkspace_sptr iws = ws;

CPUTimer tim;

SaveMD alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", "SaveMDTest_ws") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", filename) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("MakeFileBacked","0") );
alg.execute();
TS_ASSERT( alg.isExecuted() );

ws->getBoxController()->closeFile(true);
// if (Poco::File(filename).exists()) Poco::File(filename).remove();

}


/** Run SaveMD with the MDHistoWorkspace */
void doTestHisto(MDHistoWorkspace_sptr ws)
Expand Down Expand Up @@ -172,6 +228,7 @@ class SaveMDTest : public CxxTest::TestSuite
}



};


Expand Down

0 comments on commit 88b3b77

Please sign in to comment.