Mantid
Loading...
Searching...
No Matches
LoadParameterFile.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidAPI/Progress.h"
16
17#include <Poco/DOM/AutoPtr.h>
18#include <Poco/DOM/DOMParser.h>
19#include <Poco/DOM/Document.h>
20#include <Poco/DOM/Element.h>
21#include <Poco/DOM/NodeFilter.h>
22#include <Poco/DOM/NodeIterator.h>
23#include <Poco/DOM/NodeList.h>
24#include <chrono>
25#include <filesystem>
26
28using Poco::XML::AutoPtr;
29using Poco::XML::Document;
30using Poco::XML::DOMParser;
31using Poco::XML::Element;
32
33namespace Mantid::DataHandling {
34
35DECLARE_ALGORITHM(LoadParameterFile)
36
37using namespace Kernel;
38using namespace API;
39using Geometry::Instrument;
41
44 // When used as a Child Algorithm the workspace name is not used - hence the
45 // "Anonymous" to satisfy the validator
46 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("Workspace", "Anonymous", Direction::InOut),
47 "The name of the workspace to load the instrument parameters into.");
48 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::OptionalLoad, ".xml"),
49 "The filename (including its full or relative path) of a parameter "
50 "definition file. The file extension must either be .xml or .XML.");
51 declareProperty("ParameterXML", "", "The parameter definition XML as a string.");
52}
53
62 // Retrieve the filename from the properties
63 std::string filename = getPropertyValue("Filename");
64
65 // Retrieve the parameter XML string from the properties
66 const Property *const parameterXMLProperty = getProperty("ParameterXML"); // to check whether it is default
67 const std::string parameterXML = getPropertyValue("ParameterXML");
68
69 // Check the two properties (at least one must be set)
70 if (filename.empty() && parameterXMLProperty->isDefault()) {
71 throw Kernel::Exception::FileError("Either the Filename or ParameterXML "
72 "property of LoadParameterFile most be "
73 "specified to load an IDF",
74 filename);
75 }
76
77 // Get the input workspace
78 const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");
79
80 const auto instrument = localWorkspace->getInstrument()->baseInstrument();
81
82 // Set up the DOM parser and parse xml file
83 DOMParser pParser;
84 AutoPtr<Document> pDoc;
85
86 // Progress reporting object
87 Progress prog(this, 0.0, 1.0, 100);
88
89 prog.report("Parsing XML");
90
91 const auto parseStartTime = std::chrono::high_resolution_clock::now();
92 // If we've been given an XML string parse that instead
93 if (!parameterXMLProperty->isDefault()) {
94 try {
95 g_log.information("Parsing from ParameterXML property.");
96 pDoc = pParser.parseString(parameterXML);
97 } catch (Poco::Exception &exc) {
98 throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse parameter XML string", "ParameterXML");
99 } catch (...) {
100 throw Kernel::Exception::FileError("Unable to parse parameter XML string", "ParameterXML");
101 }
102 } else {
103 try {
104 // First see if the file exists
105 std::filesystem::path ipfFile(filename);
106 if (!std::filesystem::exists(ipfFile)) {
107 std::filesystem::path filePath(filename);
108 filename =
109 (std::filesystem::path(Kernel::ConfigService::Instance().getInstrumentDirectory()) / filePath.filename())
110 .string();
111 }
112 g_log.information() << "Parsing from XML file: " << filename << '\n';
113 pDoc = pParser.parse(filename);
114 } catch (Poco::Exception &exc) {
115 throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse File:", filename);
116 } catch (...) {
117 throw Kernel::Exception::FileError("Unable to parse File:", std::move(filename));
118 }
119 }
120 addTimer("xmlParsing", parseStartTime, std::chrono::high_resolution_clock::now());
121
122 // Get pointer to root element
123 Element *pRootElem = pDoc->documentElement();
124 if (!pRootElem->hasChildNodes()) {
125 throw Kernel::Exception::InstrumentDefinitionError("No root element in XML Parameter file", filename);
126 }
127
128 // Set all parameters that specified in all component-link elements of pRootElem
129 const auto linkStartTime = std::chrono::high_resolution_clock::now();
131 InstrumentParameterCache logfileCache;
132 loadInstr.setComponentLinks(instrument, pRootElem, logfileCache, &prog, localWorkspace->getWorkspaceStartDate());
133 // The parameters belong to this workspace only, not to the instrument it shares with others
134 auto &componentInfo = localWorkspace->mutableComponentInfo();
135 for (const auto &[key, parameter] : logfileCache) {
136 const auto index = componentInfo.indexOfOrInvalid(key.second);
138 componentInfo.addLogfileParameter(index, key.first, parameter);
139 }
140 }
141 addTimer("setComponentLinks", linkStartTime, std::chrono::high_resolution_clock::now());
142
143 // populate parameter map of workspace
144 const auto populateStartTime = std::chrono::high_resolution_clock::now();
145 localWorkspace->populateInstrumentParameters();
146 addTimer("populateInstrumentParameters", populateStartTime, std::chrono::high_resolution_clock::now());
147
148 if (!filename.empty()) {
149 localWorkspace->instrumentParameters().addParameterFilename(filename);
150 }
151
152 prog.resetNumSteps(1, 0.0, 1.0);
153 prog.report("Done");
154}
155
156} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
std::map< DeltaEMode::Type, std::string > index
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Kernel::Logger & g_log
Definition Algorithm.h:426
void addTimer(const std::string &name, const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end)
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
void init() override
Initialisation method.
void exec() override
Executes the algorithm.
static constexpr size_t invalidIndex
Returned by indexOfOrInvalid() for a component ID that is not part of this instrument.
Creates an instrument data from a XML instrument description file.
void setComponentLinks(std::shared_ptr< Geometry::Instrument > &instrument, Poco::XML::Element *pRootElem, Kernel::ProgressBase *progress=nullptr, const std::string &requestedDate=std::string())
Add/overwrite any parameters specified in instrument with param values specified in <component-link> ...
Records the filename and the description of failure.
Definition Exception.h:98
Exception for errors associated with the instrument definition.
Definition Exception.h:220
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
void resetNumSteps(int64_t nsteps, double start, double end)
Change the number of steps between start/end.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Base class for properties.
Definition Property.h:95
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::map< std::pair< std::string, const IComponent * >, std::shared_ptr< XMLInstrumentParameter > > InstrumentParameterCache
Convenience typedef.
Definition Instrument.h:40
@ InOut
Both an input & output workspace.
Definition Property.h:56