Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/8546_load_parameter_file…
Browse files Browse the repository at this point in the history
…_string'
  • Loading branch information
Anders-Markvardsen committed Dec 12, 2013
2 parents b370a24 + c21d90a commit 15c7c79
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 39 deletions.
Expand Up @@ -84,7 +84,7 @@ namespace Mantid
/// Algorithm's category for identification overriding a virtual method
virtual const std::string category() const { return "DataHandling\\Instrument";}

static void execManually(std::string filename, Mantid::API::ExperimentInfo_sptr localWorkspace);
static void execManually(bool useString, std::string filename, std::string parameterString, Mantid::API::ExperimentInfo_sptr localWorkspace);

private:
/// Sets documentation strings for this algorithm
Expand Down
Expand Up @@ -90,7 +90,7 @@ void LoadIDFFromNexus::runLoadParameterFile(const MatrixWorkspace_sptr & workspa
const std::string paramFile = directory + instrumentName + "_Parameters.xml";

try {
LoadParameterFile::execManually(paramFile, workspace);
LoadParameterFile::execManually(false, paramFile,"", workspace);
} catch ( std::runtime_error& ) {
g_log.notice() << "File " << paramFile << " not found or un-parsable. "
"However, the instrument has been loaded successfully.\n";
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp
Expand Up @@ -237,7 +237,7 @@ namespace Mantid
try
{
// To allow the use of ExperimentInfo instead of workspace, we call it manually
LoadParameterFile::execManually(fullPathParamIDF, m_workspace);
LoadParameterFile::execManually(false, fullPathParamIDF, "", m_workspace);
g_log.debug("Parameters loaded successfully.");
} catch (std::invalid_argument& e)
{
Expand Down
67 changes: 48 additions & 19 deletions Code/Mantid/Framework/DataHandling/src/LoadParameterFile.cpp
Expand Up @@ -35,6 +35,7 @@ This algorithm allows instrument parameters to be specified in a separate file f
#include <Poco/DOM/NodeList.h>
#include <Poco/DOM/NodeIterator.h>
#include <Poco/DOM/NodeFilter.h>
#include <Poco/DOM/AutoPtr.h>
#include <Poco/File.h>
#include <sstream>
#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
Expand All @@ -46,6 +47,7 @@ using Poco::XML::Node;
using Poco::XML::NodeList;
using Poco::XML::NodeIterator;
using Poco::XML::NodeFilter;
using Poco::XML::AutoPtr;
using Mantid::Geometry::InstrumentDefinitionParser;


Expand All @@ -59,8 +61,8 @@ DECLARE_ALGORITHM(LoadParameterFile)
/// Sets documentation strings for this algorithm
void LoadParameterFile::initDocs()
{
this->setWikiSummary("Loads instrument parameters into a [[workspace]]. where these parameters are associated component names as defined in Instrument Definition File ([[InstrumentDefinitionFile|IDF]]).");
this->setOptionalMessage("Loads instrument parameters into a workspace. where these parameters are associated component names as defined in Instrument Definition File (IDF).");
this->setWikiSummary("Loads instrument parameters into a [[workspace]]. where these parameters are associated component names as defined in Instrument Definition File ([[InstrumentDefinitionFile|IDF]]) or a string consisting of the contents of such..");
this->setOptionalMessage("Loads instrument parameters into a workspace. where these parameters are associated component names as defined in Instrument Definition File (IDF) or a string consisting of the contents of such.");
}


Expand All @@ -80,8 +82,9 @@ void LoadParameterFile::init()
declareProperty(
new WorkspaceProperty<MatrixWorkspace>("Workspace","Anonymous",Direction::InOut),
"The name of the workspace to load the instrument parameters into." );
declareProperty(new FileProperty("Filename","", FileProperty::Load, ".xml"),
"The filename (including its full or relative path) of a parameter defintion file. The file extension must either be .xml or .XML.");
declareProperty(new FileProperty("Filename","", FileProperty::OptionalLoad, ".xml"),
"The filename (including its full or relative path) of a parameter definition file. The file extension must either be .xml or .XML.");
declareProperty("ParameterXML","","The parameter definition XML as a string.");
}

/** Executes the algorithm. Reading in the file and creating and populating
Expand All @@ -95,31 +98,58 @@ void LoadParameterFile::exec()
// Retrieve the filename from the properties
std::string filename = getPropertyValue("Filename");

// Retrieve the parameter XML string from the properties
const Property * const parameterXMLProperty = getProperty("ParameterXML"); // to check whether it is default
std::string parameterXML = getPropertyValue("ParameterXML");

// Check the two properties (at least one must be set)
if( filename.empty() && parameterXMLProperty->isDefault()){
throw Kernel::Exception::FileError("Either the Filename or ParameterXML property of LoadParameterFile most be specified to load an IDF" , filename);
}

// Get the input workspace
const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");

execManually(filename, localWorkspace);
execManually(!parameterXMLProperty->isDefault(), filename, parameterXML, localWorkspace);
}

void LoadParameterFile::execManually(std::string filename, Mantid::API::ExperimentInfo_sptr localWorkspace)
void LoadParameterFile::execManually(bool useString, std::string filename, std::string parameterXML, Mantid::API::ExperimentInfo_sptr localWorkspace)
{
// TODO: Refactor to remove the need for the const cast
// TODO: Refactor to remove the need for the const cast (ticket #8521)
Instrument_sptr instrument = boost::const_pointer_cast<Instrument>(localWorkspace->getInstrument()->baseInstrument());

// Set up the DOM parser and parse xml file
DOMParser pParser;
Document* pDoc;
try
{
pDoc = pParser.parse(filename);
}
catch(Poco::Exception& exc)
{
throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse File:", filename);
}
catch(...)
AutoPtr<Document> pDoc;

if(useString){
try
{
pDoc = pParser.parseString(parameterXML);
}
catch(Poco::Exception& exc)
{
throw Kernel::Exception::FileError (exc.displayText() + ". Unable to parse parameter XML string","ParameterXML");
}
catch(...)
{
throw Kernel::Exception::FileError("Unable to parse parameter XML string","ParameterXML");
}
}
else
{
throw Kernel::Exception::FileError("Unable to parse File:" , filename);
try
{
pDoc = pParser.parse(filename);
}
catch(Poco::Exception& exc)
{
throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse File:", filename);
}
catch(...)
{
throw Kernel::Exception::FileError("Unable to parse File:" , filename);
}
}

// Get pointer to root element
Expand All @@ -136,7 +166,6 @@ void LoadParameterFile::execManually(std::string filename, Mantid::API::Experime
// populate parameter map of workspace
localWorkspace->populateInstrumentParameters();

pDoc->release();
}

} // namespace DataHandling
Expand Down
114 changes: 97 additions & 17 deletions Code/Mantid/Framework/DataHandling/test/LoadParameterFileTest.h
Expand Up @@ -30,24 +30,9 @@ class LoadParameterFileTest : public CxxTest::TestSuite

void testExecIDF_for_unit_testing2() // IDF stands for Instrument Definition File
{
LoadInstrument loaderIDF2;

TS_ASSERT_THROWS_NOTHING(loaderIDF2.initialize());

//create a workspace with some sample data
wsName = "LoadParameterFileTestIDF2";
Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",1,1,1);
Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);

//put this workspace in the data service
TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));

// Path to test input file assumes Test directory checked out from SVN
loaderIDF2.setPropertyValue("Filename", "IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING2.xml");
//inputFile = loaderIDF2.getPropertyValue("Filename");
loaderIDF2.setPropertyValue("Workspace", wsName);
TS_ASSERT_THROWS_NOTHING(loaderIDF2.execute());
TS_ASSERT( loaderIDF2.isExecuted() );
// Create workspace wsName
load_IDF2();

// load in additional parameters
LoadParameterFile loaderPF;
Expand Down Expand Up @@ -91,6 +76,101 @@ class LoadParameterFileTest : public CxxTest::TestSuite

}

void testExec_withIDFString() // Test use of string instead of file
{

// Create workspace
load_IDF2();

// Define parameter XML string
std::string parameterXML =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
"<parameter-file instrument=\"IDF_for_UNIT_TESTING2\" valid-from=\"blah...\">"
" <component-link name=\"nickel-holder\">"
" <parameter name=\"fjols-test-paramfile\"> <value val=\"2010.0\" /> </parameter>"
" </component-link>"
" <component-link name=\"IDF_for_UNIT_TESTING2.xml/combined translation6\" >"
" <parameter name=\"fjols-test-paramfile\"> <value val=\"52.0\" /> </parameter>"
" </component-link>"
"</parameter-file>";

// load in additional parameters
LoadParameterFile loaderPF;
TS_ASSERT_THROWS_NOTHING(loaderPF.initialize());
loaderPF.setPropertyValue("ParameterXML", parameterXML);
loaderPF.setPropertyValue("Workspace", wsName);
TS_ASSERT_THROWS_NOTHING(loaderPF.execute());
TS_ASSERT( loaderPF.isExecuted() );

// Get back the saved workspace
MatrixWorkspace_sptr output;
TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName));

ParameterMap& paramMap = output->instrumentParameters();
boost::shared_ptr<const Instrument> i = output->getInstrument();
boost::shared_ptr<const IDetector> ptrDet = i->getDetector(1008);
TS_ASSERT_EQUALS( ptrDet->getID(), 1008);
TS_ASSERT_EQUALS( ptrDet->getName(), "combined translation6");
Parameter_sptr param = paramMap.get(&(*ptrDet), "fjols");
TS_ASSERT_DELTA( param->value<double>(), 20.0, 0.0001);
param = paramMap.get(&(*ptrDet), "nedtur");
TS_ASSERT_DELTA( param->value<double>(), 77.0, 0.0001);
param = paramMap.get(&(*ptrDet), "fjols-test-paramfile");
TS_ASSERT_DELTA( param->value<double>(), 52.0, 0.0001);

std::vector<double> dummy = paramMap.getDouble("nickel-holder", "klovn");
TS_ASSERT_DELTA( dummy[0], 1.0, 0.0001);
dummy = paramMap.getDouble("nickel-holder", "pos");
TS_ASSERT_EQUALS (dummy.size(), 0);
dummy = paramMap.getDouble("nickel-holder", "rot");
TS_ASSERT_EQUALS (dummy.size(), 0);
dummy = paramMap.getDouble("nickel-holder", "taabe");
TS_ASSERT_DELTA (dummy[0], 200.0, 0.0001);
dummy = paramMap.getDouble("nickel-holder", "mistake");
TS_ASSERT_EQUALS (dummy.size(), 0);
dummy = paramMap.getDouble("nickel-holder", "fjols-test-paramfile");
TS_ASSERT_DELTA (dummy[0], 2010.0, 0.0001);

AnalysisDataService::Instance().remove(wsName);

}

void test_failure_if_no_file_or_string()
{
// Create workspace
load_IDF2();

// Run algorithm without file or string properties set
LoadParameterFile loaderPF;
TS_ASSERT_THROWS_NOTHING(loaderPF.initialize());
loaderPF.setPropertyValue("Workspace", wsName);
TS_ASSERT_THROWS_NOTHING(loaderPF.execute());
TS_ASSERT( ! loaderPF.execute() )
}

void load_IDF2()
{
LoadInstrument loaderIDF2;

TS_ASSERT_THROWS_NOTHING(loaderIDF2.initialize());

//create a workspace with some sample data
wsName = "LoadParameterFileTestIDF2";
Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",1,1,1);
Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);

//put this workspace in the data service
TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));

// Path to test input file assumes Test directory checked out from git
loaderIDF2.setPropertyValue("Filename", "IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING2.xml");
//inputFile = loaderIDF2.getPropertyValue("Filename");
loaderIDF2.setPropertyValue("Workspace", wsName);
TS_ASSERT_THROWS_NOTHING(loaderIDF2.execute());
TS_ASSERT( loaderIDF2.isExecuted() );

}


private:
std::string inputFile;
Expand Down

0 comments on commit 15c7c79

Please sign in to comment.