16#include "MantidIndexing/IndexInfo.h"
28using namespace Kernel;
30using namespace Geometry;
31using namespace DataObjects;
32using namespace HistogramData;
35const std::vector<std::string> validFilenameExtensions{
".xml",
".hdf5",
".nxs",
".nxs.h5"};
36enum class FilenameExtensionEnum { XML, HDF5, NXS, NXS_H5, enum_count };
37typedef EnumeratedString<FilenameExtensionEnum, &validFilenameExtensions, &compareStringsCaseInsensitive>
47 std::string ext{std::filesystem::path(filename).extension().string()};
48 std::string stem{std::filesystem::path(filename).stem().string()};
49 std::string pre_ext{std::filesystem::path(stem).extension().string()};
52 if (!pre_ext.empty()) {
54 const std::string double_ext{pre_ext + ext};
55 FilenameExtension fne(double_ext);
57 }
catch (
const std::runtime_error &) {
63 FilenameExtension fne(ext);
65 }
catch (std::runtime_error &) {
68 std::ostringstream os;
69 os <<
"Instrument file name \"" << filename <<
"\" has an invalid extension.";
70 throw std::runtime_error(os.str());
75 return validFilenameExtensions;
85 const std::string &filePath = descriptor.
filename();
91 std::string::size_type stripPath = filePath.find_last_of(
"\\/");
92 if (stripPath == std::string::npos)
94 if (filePath.find(
"Definition", stripPath) != std::string::npos) {
110 "Path to a file (full or relative) defining the instrument. The file could be an"
111 " IDF or a NeXus Geometry file. Note, Filename or InstrumentName must be specified, but not both.");
113 "Name of instrument. Can be used instead of Filename to "
116 "The name of the workspace in which to store the imported instrument");
118 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
119 mustBePositive->setLower(0.0);
121 "This value affects the colour of the detectors in the instrument\n"
122 "display window (default 1)");
124 "This value affects the colour of the monitors in the instrument\n"
125 "display window (default 2)");
128 "Set to True to create an EventWorkspace (with no events) "
129 "instead of a Workspace2D.");
149 if (!instrumentName.empty())
153 switch (enFilenameExtension) {
154 case FilenameExtensionEnum::XML:
155 case FilenameExtensionEnum::HDF5:
158 case FilenameExtensionEnum::NXS:
159 case FilenameExtensionEnum::NXS_H5:
163 std::ostringstream os;
164 os <<
"Instrument file name has an invalid extension: "
165 <<
"\"" << enFilenameExtension.c_str() <<
"\"";
166 throw std::runtime_error(os.str());
170 auto timerStart = std::chrono::high_resolution_clock::now();
172 addTimer(
"getInstrument", timerStart, std::chrono::high_resolution_clock::now());
175 timerStart = std::chrono::high_resolution_clock::now();
176 const size_t number_spectra = instrument->getNumberDetectors();
177 addTimer(
"getNumberDetectors", timerStart, std::chrono::high_resolution_clock::now());
180 if (number_spectra == 0) {
181 g_log.
error(
"Instrument has no detectors, unable to create workspace for it");
185 timerStart = std::chrono::high_resolution_clock::now();
186 Indexing::IndexInfo indexInfo(number_spectra);
187 addTimer(
"createIndexInfo", timerStart, std::chrono::high_resolution_clock::now());
188 bool MakeEventWorkspace =
getProperty(
"MakeEventWorkspace");
190 if (MakeEventWorkspace) {
192 create<EventWorkspace>(instrument, indexInfo, BinEdges{0.0, std::numeric_limits<double>::min()}));
194 timerStart = std::chrono::high_resolution_clock::now();
195 const double detector_value =
getProperty(
"DetectorValue");
196 const double monitor_value =
getProperty(
"MonitorValue");
197 auto ws2D = create<Workspace2D>(
198 instrument, indexInfo,
199 Histogram(BinEdges{0.0, 1.0}, Counts(1, detector_value), CountStandardDeviations(1, detector_value)));
200 addTimer(
"makeWorkspace2D", timerStart, std::chrono::high_resolution_clock::now());
202 if (monitor_value != detector_value) {
203 timerStart = std::chrono::high_resolution_clock::now();
204 Counts v_monitor_y(1, monitor_value);
205 CountStandardDeviations v_monitor_e(1, monitor_value);
207 const auto &spectrumInfo = ws2D->spectrumInfo();
208 const auto size =
static_cast<int64_t
>(spectrumInfo.size());
209#pragma omp parallel for
210 for (int64_t i = 0; i < size; i++) {
211 if (spectrumInfo.isMonitor(i)) {
212 ws2D->setCounts(i, v_monitor_y);
213 ws2D->setCountStandardDeviations(i, v_monitor_e);
216 addTimer(
"setMonitors", timerStart, std::chrono::high_resolution_clock::now());
224 const std::string &instrumentname) {
228 loadInst->setPropertyValue(
"Filename", filename);
229 loadInst->setPropertyValue(
"InstrumentName", instrumentname);
230 loadInst->setProperty(
"RewriteSpectraMap",
OptionalBool(
true));
240 const std::string instrumentEntryName{
"/instrument/instrument_xml"};
242 bool foundIDF{
false};
243 std::string instrumentParentEntryName;
248 foundIDF = nxsfile.
isEntry(instrumentParentEntryName + instrumentEntryName);
252 throw std::runtime_error(
"No instrument XML definition found in " + filename +
" at " + instrumentParentEntryName +
253 instrumentEntryName);
261 loadInst->setPropertyValue(
"Filename", filename);
263 loadInst->setPropertyValue(
"InstrumentParentPath", instrumentParentEntryName);
265 }
catch (std::invalid_argument &) {
266 getLogger().
error(
"Invalid argument to LoadIDFFromNexus Child Algorithm ");
267 }
catch (std::runtime_error &) {
268 getLogger().
debug(
"No instrument definition found by LoadIDFFromNexus in " + filename +
" at " +
269 instrumentParentEntryName + instrumentEntryName);
272 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.
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.
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...
bool isEntry(std::string const &entryName, std::string const &groupClass) const
Checks if a full-address entry exists for a particular groupClass in a Nexus dataset.
std::pair< std::string, std::string > const & firstEntryNameType() const noexcept
Returns the name & type of the first entry in the file.
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.