13#include "MantidNexus/NexusFile.h"
15#include <Poco/DOM/DOMParser.h>
16#include <Poco/DOM/Document.h>
17#include <Poco/DOM/Element.h>
18#include <Poco/DOM/NodeIterator.h>
19#include <Poco/DOM/NodeList.h>
21using Poco::XML::Document;
22using Poco::XML::DOMParser;
23using Poco::XML::Element;
24using Poco::XML::NodeList;
30using namespace Kernel;
32using Types::Core::DateAndTime;
42 "The name of the workspace in which to attach the imported instrument");
44 const std::vector<std::string> exts{
".nxs",
".nxs.h5"};
46 "The name (including its full or relative path) of the Nexus file to "
47 "attempt to load the instrument from.");
50 "Path name within the Nexus tree of the folder containing "
51 "the instrument folder. "
52 "For example it is 'raw_data_1' for an ISIS raw Nexus file "
53 "and 'mantid_workspace_1' for a processed nexus file. "
54 "Only a one level path is curently supported",
57 "Full path name of Parameter Correction file. "
58 "This should only be used in a situation,"
59 "where the default full file path is inconvenient.",
76 std::string instrumentParentAddress =
getPropertyValue(
"InstrumentParentPath");
79 Nexus::File nxfile(filename);
81 nxfile.openAddress(instrumentParentAddress);
84 localWorkspace->loadInstrumentInfoNexus(filename, &nxfile);
87 std::string parameterCorrectionFile =
getPropertyValue(
"ParameterCorrectionFilePath");
88 if (parameterCorrectionFile.empty()) {
91 g_log.
debug() <<
"Parameter correction file: " << parameterCorrectionFile <<
"\n";
94 std::string correctionParameterFile;
96 if (!parameterCorrectionFile.empty()) {
100 g_log.
notice() <<
"Using parameter correction file: " << parameterCorrectionFile <<
".\n";
102 correctionParameterFile, append);
107 if (correctionParameterFile.empty() || append) {
110 g_log.
notice() <<
"Parameters to be replaced are cleared.\n";
111 localWorkspace->getInstrument()->getParameterMap()->clear();
115 if (!correctionParameterFile.empty()) {
116 std::filesystem::path corrFilePath(parameterCorrectionFile);
117 g_log.
debug() <<
"Correction file path: " << corrFilePath.string() <<
"\n";
118 std::filesystem::path corrDirPath = corrFilePath.parent_path();
119 g_log.
debug() <<
"Correction directory path: " << corrDirPath.string() <<
"\n";
120 std::filesystem::path corrParamFile(corrDirPath / correctionParameterFile);
122 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.string() <<
" to append parameters.\n";
124 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.string() <<
" to replace parameters.\n";
128 g_log.
notice() <<
"No correction parameter file applies to the date for "
129 "correction file.\n";
140 std::vector<std::string> directoryNames = ConfigService::Instance().getInstrumentDirectories();
141 for (
auto &directoryName : directoryNames) {
144 std::filesystem::path iPath =
145 std::filesystem::path(directoryName) /
"embedded_instrument_corrections";
147 if (std::filesystem::exists(iPath) && std::filesystem::is_directory(iPath)) {
148 std::filesystem::path ipFile = iPath / (instName +
"_Parameter_Corrections.xml");
149 if (std::filesystem::exists(ipFile) && std::filesystem::is_regular_file(ipFile)) {
150 return ipFile.string();
171 std::string ¶meter_file,
bool &append) {
179 g_log.
notice() <<
"No date is supplied for parameter correction file " << correction_file
180 <<
". Correction file is ignored.\n";
189 Poco::AutoPtr<Document> pDoc;
191 pDoc = pParser.parseString(xmlText);
192 }
catch (Poco::Exception &exc) {
199 Element *pRootElem = pDoc->documentElement();
200 if (!pRootElem->hasChildNodes()) {
201 g_log.
error(
"Parameter correction file: " + correction_file +
"contains no XML root element.");
207 g_log.
notice() <<
"Date for correction file " << date <<
"\n";
208 DateAndTime externalDate(date);
211 Poco::AutoPtr<NodeList> correctionNodeList = pRootElem->getElementsByTagName(
"correction");
212 for (
unsigned long i = 0; i < correctionNodeList->length(); ++i) {
214 auto *corr =
dynamic_cast<Element *
>(correctionNodeList->item(i));
216 DateAndTime start(corr->getAttribute(
"valid-from"));
217 DateAndTime end(corr->getAttribute(
"valid-to"));
218 if (start <= externalDate && externalDate <= end) {
219 parameter_file = corr->getAttribute(
"file");
220 append = (corr->getAttribute(
"append") ==
"true");
224 g_log.
error(
"Parameter correction file: " + correction_file +
"contains an invalid correction element.");
241 std::string parameterString;
244 nxfile->openGroup(
"instrument",
"NXinstrument");
245 localWorkspace->loadInstrumentParametersNexus(nxfile, parameterString);
246 nxfile->closeGroup();
250 localWorkspace->populateInstrumentParameters();
252 if (parameterString.empty()) {
255 std::vector<std::string> directoryNames = ConfigService::Instance().getInstrumentDirectories();
256 const std::string instrumentName = localWorkspace->getInstrument()->getName();
257 for (
const auto &directoryName : directoryNames) {
260 const std::string paramFile = directoryName + instrumentName +
"_Parameters.xml";
268 g_log.
notice() <<
"Found Instrument parameter map entry in Nexus file, "
269 "which is loaded.\n\n";
271 localWorkspace->readParameterMap(parameterString);
283 loadParamAlg->setProperty(
"Filename", fullPathName);
284 loadParamAlg->setProperty(
"Workspace", localWorkspace);
285 loadParamAlg->execute();
286 g_log.
notice() <<
"Instrument parameter file: " << fullPathName <<
" has been loaded.\n\n";
288 }
catch (std::invalid_argument &e) {
289 g_log.
information(
"LoadParameterFile: No parameter file found for this instrument");
291 }
catch (std::runtime_error &e) {
292 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 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 LoadParameters(Nexus::File *nxfile, const API::MatrixWorkspace_sptr &localWorkspace)
Load the parameters from Nexus file if possible, else from parameter file, into workspace.
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.
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.