Newer
Older
Anders Markvardsen
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
Anders Markvardsen
committed
#include "MantidDataHandling/LoadParameterFile.h"
Federico Montesino Pouzols
committed
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/Progress.h"
Russell Taylor
committed
#include "MantidGeometry/Instrument.h"
Anders Markvardsen
committed
#include "MantidGeometry/Instrument/Component.h"
Federico Montesino Pouzols
committed
#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/DOM/NodeIterator.h>
#include <Poco/DOM/NodeFilter.h>
#include <Poco/DOM/AutoPtr.h>
Anders Markvardsen
committed
using Poco::XML::DOMParser;
using Poco::XML::Document;
using Poco::XML::Element;
using Poco::XML::Node;
using Poco::XML::NodeList;
using Poco::XML::NodeIterator;
using Poco::XML::NodeFilter;
using Mantid::Geometry::InstrumentDefinitionParser;
Anders Markvardsen
committed
namespace Mantid {
namespace DataHandling {
Anders Markvardsen
committed
Anders Markvardsen
committed
DECLARE_ALGORITHM(LoadParameterFile)
Anders Markvardsen
committed
using namespace Kernel;
using namespace API;
Gigg, Martyn Anthony
committed
using Geometry::Instrument;
Russell Taylor
committed
using Geometry::Instrument_sptr;
Anders Markvardsen
committed
/// Empty default constructor
LoadParameterFile::LoadParameterFile() : Algorithm() {}
Anders Markvardsen
committed
/// Initialisation method.
void LoadParameterFile::init() {
// When used as a Child Algorithm the workspace name is not used - hence the
// "Anonymous" to satisfy the validator
Anders Markvardsen
committed
declareProperty(
make_unique<WorkspaceProperty<MatrixWorkspace>>("Workspace", "Anonymous",
Direction::InOut),
"The name of the workspace to load the instrument parameters into.");
declareProperty(
make_unique<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.");
Anders Markvardsen
committed
}
/** Executes the algorithm. Reading in the file and creating and populating
* the output workspace
*
* @throw FileError Thrown if unable to parse XML file
* @throw InstrumentDefinitionError Thrown if issues with the content of XML
*instrument file
Anders Markvardsen
committed
*/
Anders Markvardsen
committed
// Retrieve the filename from the properties
std::string filename = getPropertyValue("Filename");
Anders Markvardsen
committed
// Retrieve the parameter XML string from the properties
const Property *const parameterXMLProperty =
getProperty("ParameterXML"); // to check whether it is default
const 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);
Anders Markvardsen
committed
// Get the input workspace
const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");
// TODO: Refactor to remove the need for the const cast (ticket #8521)
Instrument_sptr instrument = boost::const_pointer_cast<Instrument>(
localWorkspace->getInstrument()->baseInstrument());
Anders Markvardsen
committed
// Set up the DOM parser and parse xml file
DOMParser pParser;
Progress prog(this, 0.0, 1.0, 100);
prog.report("Parsing XML");
// If we've been given an XML string parse that instead
if (!parameterXMLProperty->isDefault()) {
try {
g_log.information("Parsing from ParameterXML property.");
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");
// First see if the file exists
Poco::File ipfFile(filename);
Poco::Path filePath(filename);
filename =
Poco::Path(
Kernel::ConfigService::Instance().getInstrumentDirectory())
.makeDirectory()
.setFileName(filePath.getFileName())
.toString();
g_log.information() << "Parsing from XML file: " << filename << '\n';
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);
Anders Markvardsen
committed
}
Anders Markvardsen
committed
Anders Markvardsen
committed
// Get pointer to root element
Element *pRootElem = pDoc->documentElement();
if (!pRootElem->hasChildNodes()) {
throw Kernel::Exception::InstrumentDefinitionError(
"No root element in XML Parameter file", filename);
Anders Markvardsen
committed
}
// Set all parameters that specified in all component-link elements of
// pRootElem
InstrumentDefinitionParser loadInstr;
loadInstr.setComponentLinks(instrument, pRootElem, &prog);
Anders Markvardsen
committed
// populate parameter map of workspace
Anders Markvardsen
committed
localWorkspace->populateInstrumentParameters();
localWorkspace->instrumentParameters().addParameterFilename(filename);
}
Anders Markvardsen
committed
prog.resetNumSteps(1, 0.0, 1.0);
prog.report("Done");
Anders Markvardsen
committed
}
} // namespace DataHandling
} // namespace Mantid