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"};
47 "The name (including its full or relative path) of the Nexus file to attempt to load the instrument from.");
50 "InstrumentParentPath", std::string(
""),
51 "Path name within the Nexus tree of the folder containing the instrument folder. "
52 "For example it is 'raw_data_1' for an ISIS raw Nexus file and 'mantid_workspace_1' for a processed nexus file. "
53 "Only a one level path is curently supported",
56 "Full path name of Parameter Correction file. "
57 "This should only be used in a situation,where the default full file path is inconvenient.",
74 std::string instrumentParentAddress =
getPropertyValue(
"InstrumentParentPath");
77 Nexus::File nxfile(filename);
79 nxfile.openAddress(instrumentParentAddress);
82 localWorkspace->loadInstrumentInfoNexus(filename, &nxfile);
85 std::string parameterCorrectionFile =
getPropertyValue(
"ParameterCorrectionFilePath");
86 if (parameterCorrectionFile.empty()) {
89 g_log.
debug() <<
"Parameter correction file: " << parameterCorrectionFile <<
"\n";
92 std::string correctionParameterFile;
94 if (!parameterCorrectionFile.empty()) {
98 g_log.
notice() <<
"Using parameter correction file: " << parameterCorrectionFile <<
".\n";
100 correctionParameterFile, append);
105 if (correctionParameterFile.empty() || append) {
108 g_log.
notice() <<
"Parameters to be replaced are cleared.\n";
109 localWorkspace->getInstrument()->getParameterMap()->clear();
113 if (!correctionParameterFile.empty()) {
114 std::filesystem::path corrFilePath(parameterCorrectionFile);
115 g_log.
debug() <<
"Correction file path: " << corrFilePath.string() <<
"\n";
116 std::filesystem::path corrDirPath = corrFilePath.parent_path();
117 g_log.
debug() <<
"Correction directory path: " << corrDirPath.string() <<
"\n";
118 std::filesystem::path corrParamFile(corrDirPath / correctionParameterFile);
120 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.string() <<
" to append parameters.\n";
122 g_log.
notice() <<
"Using correction parameter file: " << corrParamFile.string() <<
" to replace parameters.\n";
126 g_log.
notice() <<
"No correction parameter file applies to the date for "
127 "correction file.\n";
138 std::vector<std::string> directoryNames = ConfigService::Instance().getInstrumentDirectories();
139 for (
auto &directoryName : directoryNames) {
142 std::filesystem::path iPath =
143 std::filesystem::path(directoryName) /
"embedded_instrument_corrections";
145 if (std::filesystem::exists(iPath) && std::filesystem::is_directory(iPath)) {
146 std::filesystem::path ipFile = iPath / (instName +
"_Parameter_Corrections.xml");
147 if (std::filesystem::exists(ipFile) && std::filesystem::is_regular_file(ipFile)) {
148 return ipFile.string();
169 std::string ¶meter_file,
bool &append) {
177 g_log.
notice() <<
"No date is supplied for parameter correction file " << correction_file
178 <<
". Correction file is ignored.\n";
187 Poco::AutoPtr<Document> pDoc;
189 pDoc = pParser.parseString(xmlText);
190 }
catch (Poco::Exception &exc) {
197 Element *pRootElem = pDoc->documentElement();
198 if (!pRootElem->hasChildNodes()) {
199 g_log.
error(
"Parameter correction file: " + correction_file +
"contains no XML root element.");
205 g_log.
notice() <<
"Date for correction file " << date <<
"\n";
206 DateAndTime externalDate(date);
209 Poco::AutoPtr<NodeList> correctionNodeList = pRootElem->getElementsByTagName(
"correction");
210 for (
unsigned long i = 0; i < correctionNodeList->length(); ++i) {
212 auto *corr =
dynamic_cast<Element *
>(correctionNodeList->item(i));
214 DateAndTime start(corr->getAttribute(
"valid-from"));
215 DateAndTime end(corr->getAttribute(
"valid-to"));
216 if (start <= externalDate && externalDate <= end) {
217 parameter_file = corr->getAttribute(
"file");
218 append = (corr->getAttribute(
"append") ==
"true");
222 g_log.
error(
"Parameter correction file: " + correction_file +
"contains an invalid correction element.");
239 std::string parameterString;
242 nxfile->openGroup(
"instrument",
"NXinstrument");
243 localWorkspace->loadInstrumentParametersNexus(nxfile, parameterString);
244 nxfile->closeGroup();
248 localWorkspace->populateInstrumentParameters();
250 if (parameterString.empty()) {
253 std::vector<std::string> directoryNames = ConfigService::Instance().getInstrumentDirectories();
254 const std::string instrParameterFileName = localWorkspace->getInstrument()->getName() +
"_Parameters.xml";
255 for (
const auto &directoryName : directoryNames) {
257 const std::filesystem::path direc(directoryName);
258 const std::string paramFile = (direc / instrParameterFileName).
string();
266 g_log.
notice() <<
"Found Instrument parameter map entry in Nexus file, "
267 "which is loaded.\n\n";
269 localWorkspace->readParameterMap(parameterString);
280 loadParamAlg->setProperty(
"Filename", fullPathName);
281 loadParamAlg->setProperty(
"Workspace", localWorkspace);
282 loadParamAlg->execute();
283 g_log.
notice() <<
"Instrument parameter file: " << fullPathName <<
" has been loaded.\n\n";
285 }
catch (std::invalid_argument &e) {
286 g_log.
information(
"LoadParameterFile: No parameter file found for this instrument");
288 }
catch (std::runtime_error &e) {
289 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.