16#include "MantidIndexing/IndexInfo.h"
22#include "MantidNexus/NexusFile.h"
23#include "MantidNexusGeometry/NexusGeometryParser.h"
31using namespace Kernel;
33using namespace Geometry;
34using namespace DataObjects;
35using namespace HistogramData;
38const std::vector<std::string> validFilenameExtensions{
".xml",
".hdf5",
".nxs",
".nxs.h5"};
39enum class FilenameExtensionEnum { XML, HDF5, NXS, NXS_H5, enum_count };
40typedef EnumeratedString<FilenameExtensionEnum, &validFilenameExtensions, &compareStringsCaseInsensitive>
50 std::string ext{std::filesystem::path(filename).extension().string()};
51 std::string stem{std::filesystem::path(filename).stem().string()};
52 std::string pre_ext{std::filesystem::path(stem).extension().string()};
55 if (!pre_ext.empty()) {
57 const std::string double_ext{pre_ext + ext};
58 FilenameExtension fne(double_ext);
60 }
catch (
const std::runtime_error &) {
66 FilenameExtension fne(ext);
68 }
catch (std::runtime_error &) {
71 std::ostringstream os;
72 os <<
"Instrument file name \"" << filename <<
"\" has an invalid extension.";
73 throw std::runtime_error(os.str());
78 return validFilenameExtensions;
88 const std::string &filePath = descriptor.
filename();
94 std::string::size_type stripPath = filePath.find_last_of(
"\\/");
95 if (stripPath == std::string::npos)
97 if (filePath.find(
"Definition", stripPath) != std::string::npos) {
113 "Path to a file (full or relative) defining the instrument. The file could be an"
114 " IDF or a NeXus Geometry file. Note, Filename or InstrumentName must be specified, but not both.");
116 "Name of instrument. Can be used instead of Filename to "
119 "The name of the workspace in which to store the imported instrument");
121 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
122 mustBePositive->setLower(0.0);
124 "This value affects the colour of the detectors in the instrument\n"
125 "display window (default 1)");
127 "This value affects the colour of the monitors in the instrument\n"
128 "display window (default 2)");
131 "Set to True to create an EventWorkspace (with no events) "
132 "instead of a Workspace2D.");
152 if (!instrumentName.empty())
156 switch (enFilenameExtension) {
157 case FilenameExtensionEnum::XML:
158 case FilenameExtensionEnum::HDF5:
161 case FilenameExtensionEnum::NXS:
162 case FilenameExtensionEnum::NXS_H5:
166 std::ostringstream os;
167 os <<
"Instrument file name has an invalid extension: "
168 <<
"\"" << enFilenameExtension.c_str() <<
"\"";
169 throw std::runtime_error(os.str());
176 const size_t number_spectra = instrument->getNumberDetectors();
179 if (number_spectra == 0) {
180 g_log.
error(
"Instrument has no detectors, unable to create workspace for it");
184 Indexing::IndexInfo indexInfo(number_spectra);
185 bool MakeEventWorkspace =
getProperty(
"MakeEventWorkspace");
187 if (MakeEventWorkspace) {
189 create<EventWorkspace>(instrument, indexInfo, BinEdges{0.0, std::numeric_limits<double>::min()}));
191 const double detector_value =
getProperty(
"DetectorValue");
192 const double monitor_value =
getProperty(
"MonitorValue");
193 auto ws2D = create<Workspace2D>(
194 instrument, indexInfo,
195 Histogram(BinEdges{0.0, 1.0}, Counts(1, detector_value), CountStandardDeviations(1, detector_value)));
197 Counts v_monitor_y(1, monitor_value);
198 CountStandardDeviations v_monitor_e(1, monitor_value);
200 const auto &spectrumInfo = ws2D->spectrumInfo();
201 const auto size =
static_cast<int64_t
>(spectrumInfo.size());
202#pragma omp parallel for
203 for (int64_t i = 0; i < size; i++) {
204 if (spectrumInfo.isMonitor(i)) {
205 ws2D->setCounts(i, v_monitor_y);
206 ws2D->setCountStandardDeviations(i, v_monitor_e);
215 const std::string &instrumentname) {
219 loadInst->setPropertyValue(
"Filename", filename);
220 loadInst->setPropertyValue(
"InstrumentName", instrumentname);
221 loadInst->setProperty(
"RewriteSpectraMap",
OptionalBool(
true));
231 const std::string instrumentEntryName{
"/instrument/instrument_xml"};
233 const std::string instrumentParentEntryName_1{
"mantid_workspace_1"};
234 const std::string instrumentParentEntryName_2{
"raw_data_1"};
235 std::string instrumentParentEntryName{instrumentParentEntryName_1};
238 bool foundIDF{
false};
240 Nexus::File nxsfile(filename);
241 nxsfile.openAddress(
"/" + instrumentParentEntryName + instrumentEntryName);
247 instrumentParentEntryName = instrumentParentEntryName_2;
249 Nexus::File nxsfile(filename);
250 nxsfile.openAddress(
"/" + instrumentParentEntryName + instrumentEntryName);
257 throw std::runtime_error(
"No instrument XML definition found in " + filename +
" at " +
258 instrumentParentEntryName_1 + instrumentEntryName +
" or at " +
259 instrumentParentEntryName_2 + instrumentEntryName);
267 loadInst->setPropertyValue(
"Filename", filename);
269 loadInst->setPropertyValue(
"InstrumentParentPath", instrumentParentEntryName);
271 }
catch (std::invalid_argument &) {
272 getLogger().
error(
"Invalid argument to LoadIDFFromNexus Child Algorithm ");
273 }
catch (std::runtime_error &) {
274 getLogger().
debug(
"No instrument definition found by LoadIDFFromNexus in " + filename +
" at " +
275 instrumentParentEntryName + instrumentEntryName);
278 if (!loadInst->isExecuted())
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
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.
Kernel::Logger & getLogger() const
Returns a reference to the logger.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Helper class for reporting progress from algorithms.
A property class for workspaces.
void init() override
Overwrites Algorithm method.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
static const std::vector< std::string > & getValidInstrumentFilenameExtensions()
API::MatrixWorkspace_sptr runLoadInstrument(const std::string &filename, const std::string &instrumentname)
void exec() override
Overwrites Algorithm method.
API::MatrixWorkspace_sptr runLoadIDFFromNexus(const std::string &filename)
static std::string retrieveValidInstrumentFilenameExtension(const std::string &filename)
Exception for errors associated with the instrument definition.
Defines a wrapper around an open file.
const std::string & filename() const
Access the filename.
static bool isAscii(const std::string &filename, const size_t nbytes=256)
Returns true if the file is considered ascii.
const std::string & extension() const
Access the file extension.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
OptionalBool : Tri-state bool.
void reportIncrement(int inc, const std::string &msg="")
Sends the progress notification and increment the loop counter by more than one.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class that provides for a standard Nexus exception.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
@ Output
An output workspace.