-
Notifications
You must be signed in to change notification settings - Fork 122
/
LoadParameterFile.cpp
142 lines (123 loc) · 5.44 KB
/
LoadParameterFile.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidDataHandling/LoadParameterFile.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/Progress.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/Component.h"
#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
#include "MantidKernel/ConfigService.h"
#include <Poco/DOM/AutoPtr.h>
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/NodeFilter.h>
#include <Poco/DOM/NodeIterator.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/File.h>
using Mantid::Geometry::InstrumentDefinitionParser;
using Poco::XML::AutoPtr;
using Poco::XML::Document;
using Poco::XML::DOMParser;
using Poco::XML::Element;
namespace Mantid {
namespace DataHandling {
DECLARE_ALGORITHM(LoadParameterFile)
using namespace Kernel;
using namespace API;
using Geometry::Instrument;
using Geometry::Instrument_sptr;
/// Initialisation method.
void LoadParameterFile::init() {
// When used as a Child Algorithm the workspace name is not used - hence the
// "Anonymous" to satisfy the validator
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("Workspace", "Anonymous", Direction::InOut),
"The name of the workspace to load the instrument parameters into.");
declareProperty(std::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.");
}
/** 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
*/
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
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);
}
// 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 = std::const_pointer_cast<Instrument>(localWorkspace->getInstrument()->baseInstrument());
// Set up the DOM parser and parse xml file
DOMParser pParser;
AutoPtr<Document> pDoc;
// Progress reporting object
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");
}
} else {
try {
// First see if the file exists
Poco::File ipfFile(filename);
if (!ipfFile.exists()) {
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);
}
}
// Get pointer to root element
Element *pRootElem = pDoc->documentElement();
if (!pRootElem->hasChildNodes()) {
throw Kernel::Exception::InstrumentDefinitionError("No root element in XML Parameter file", filename);
}
// Set all parameters that specified in all component-link elements of
// pRootElem
InstrumentDefinitionParser loadInstr;
loadInstr.setComponentLinks(instrument, pRootElem, &prog, localWorkspace->getWorkspaceStartDate());
// populate parameter map of workspace
localWorkspace->populateInstrumentParameters();
if (!filename.empty()) {
localWorkspace->instrumentParameters().addParameterFilename(filename);
}
prog.resetNumSteps(1, 0.0, 1.0);
prog.report("Done");
}
} // namespace DataHandling
} // namespace Mantid