14#include <Poco/DOM/DOMParser.h>
15#include <Poco/DOM/Document.h>
16#include <Poco/DOM/Element.h>
17#include <Poco/DOM/NodeIterator.h>
18#include <Poco/DOM/NodeList.h>
21#include <nexus/NeXusFile.hpp>
23using Poco::XML::Document;
24using Poco::XML::DOMParser;
25using Poco::XML::Element;
26using Poco::XML::NodeList;
32using namespace Kernel;
34using Types::Core::DateAndTime;
44 "The name of the workspace in which to attach the imported instrument");
46 const std::vector<std::string> exts{
".nxs",
".nxs.h5"};
48 "The name (including its full or relative path) of the Nexus file to "
49 "attempt to load the instrument from.");
52 "Path name within the Nexus tree of the folder containing "
53 "the instrument folder. "
54 "For example it is 'raw_data_1' for an ISIS raw Nexus file "
55 "and 'mantid_workspace_1' for a processed nexus file. "
56 "Only a one level path is curently supported",
59 "Full path name of Parameter Correction file. "
60 "This should only be used in a situation,"
61 "where the default full file path is inconvenient.",
81 ::NeXus::File nxfile(filename);
83 nxfile.openPath(instrumentParentPath);
86 localWorkspace->loadInstrumentInfoNexus(filename, &nxfile);
89 std::string parameterCorrectionFile =
getPropertyValue(
"ParameterCorrectionFilePath");
90 if (parameterCorrectionFile.empty()) {
93 g_log.
debug() <<
"Parameter correction file: " << parameterCorrectionFile <<
"\n";
96 std::string correctionParameterFile;
98 if (!parameterCorrectionFile.empty()) {
102 g_log.
notice() <<
"Using parameter correction file: " << parameterCorrectionFile <<
".\n";
104 correctionParameterFile, append);
109 if (correctionParameterFile.empty() || append) {
112 g_log.
notice() <<
"Parameters to be replaced are cleared.\n";
113 localWorkspace->getInstrument()->getParameterMap()->clear();
117 if (!correctionParameterFile.empty()) {
118 Poco::Path corrFilePath(parameterCorrectionFile);
119 g_log.
debug() <<
"Correction file path: " << corrFilePath.toString() <<
"\n";
120 Poco::Path corrDirPath = corrFilePath.parent();
121 g_log.
debug() <<
"Correction directory path: " << corrDirPath.toString() <<
"\n";
122 Poco::Path corrParamFile(corrDirPath, correctionParameterFile);
124 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.toString() <<
" to append parameters.\n";
126 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.toString() <<
" to replace parameters.\n";
130 g_log.
notice() <<
"No correction parameter file applies to the date for "
131 "correction file.\n";
143 for (
auto &directoryName : directoryNames) {
146 Poco::Path iPath(directoryName,
147 "embedded_instrument_corrections");
149 Poco::File ipDir(iPath);
150 if (ipDir.exists() && ipDir.isDirectory()) {
151 iPath.append(instName +
"_Parameter_Corrections.xml");
152 Poco::File ipFile(iPath);
153 if (ipFile.exists() && ipFile.isFile()) {
154 return ipFile.path();
175 std::string ¶meter_file,
bool &append) {
183 g_log.
notice() <<
"No date is supplied for parameter correction file " << correction_file
184 <<
". Correction file is ignored.\n";
193 Poco::AutoPtr<Document> pDoc;
195 pDoc = pParser.parseString(xmlText);
196 }
catch (Poco::Exception &exc) {
203 Element *pRootElem = pDoc->documentElement();
204 if (!pRootElem->hasChildNodes()) {
205 g_log.
error(
"Parameter correction file: " + correction_file +
"contains no XML root element.");
211 g_log.
notice() <<
"Date for correction file " << date <<
"\n";
212 DateAndTime externalDate(date);
215 Poco::AutoPtr<NodeList> correctionNodeList = pRootElem->getElementsByTagName(
"correction");
216 for (
unsigned long i = 0; i < correctionNodeList->length(); ++i) {
218 auto *corr =
dynamic_cast<Element *
>(correctionNodeList->item(i));
220 DateAndTime start(corr->getAttribute(
"valid-from"));
221 DateAndTime end(corr->getAttribute(
"valid-to"));
222 if (start <= externalDate && externalDate <= end) {
223 parameter_file = corr->getAttribute(
"file");
224 append = (corr->getAttribute(
"append") ==
"true");
228 g_log.
error(
"Parameter correction file: " + correction_file +
"contains an invalid correction element.");
245 std::string parameterString;
248 nxfile->openGroup(
"instrument",
"NXinstrument");
249 localWorkspace->loadInstrumentParametersNexus(nxfile, parameterString);
250 nxfile->closeGroup();
254 localWorkspace->populateInstrumentParameters();
256 if (parameterString.empty()) {
260 const std::string instrumentName = localWorkspace->getInstrument()->getName();
261 for (
const auto &directoryName : directoryNames) {
264 const std::string paramFile = directoryName + instrumentName +
"_Parameters.xml";
272 g_log.
notice() <<
"Found Instrument parameter map entry in Nexus file, "
273 "which is loaded.\n\n";
275 localWorkspace->readParameterMap(parameterString);
287 loadParamAlg->setProperty(
"Filename", fullPathName);
288 loadParamAlg->setProperty(
"Workspace", localWorkspace);
289 loadParamAlg->execute();
290 g_log.
notice() <<
"Instrument parameter file: " << fullPathName <<
" has been loaded.\n\n";
292 }
catch (std::invalid_argument &e) {
293 g_log.
information(
"LoadParameterFile: No parameter file found for this instrument");
295 }
catch (std::runtime_error &e) {
296 g_log.
information(
"Unable to successfully run LoadParameterFile Child Algorithm");
#define DECLARE_ALGORITHM(classname)
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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
std::string getParameterCorrectionFile(const std::string &instName)
Get the parameter correction file, if it exists else return "".
void LoadParameters(::NeXus::File *nxfile, const API::MatrixWorkspace_sptr &localWorkspace)
Load the parameters from Nexus file if possible, else from parameter file, into workspace.
void exec() override
Overwrites Algorithm method.
bool loadParameterFile(const std::string &fullPathName, const API::MatrixWorkspace_sptr &localWorkspace)
Load Parameter File specified by full pathname into given workspace, return success.
void readParameterCorrectionFile(const std::string &correction_file, const std::string &date, std::string ¶meter_file, bool &append)
Read parameter correction file, return applicabel parameter file and whether to append.
void init() override
Overwrites Algorithm method. Does nothing at present.
LoadIDFFromNexus()
Default constructor.
Records the filename and the description of failure.
Exception for errors associated with the instrument definition.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
MANTID_KERNEL_DLL std::string loadFile(const std::string &filename)
Loads the entire contents of a text file into a string.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.