16#include <nexus/NeXusFile.hpp>
17#include <nexus/NeXusException.hpp>
20#include <boost/algorithm/string.hpp>
23using namespace Kernel;
47 const static auto target_dataset =
"information";
48 for (
auto iter = entries.begin(); iter != entries.end(); ++iter) {
49 const auto grouped_entries = iter->second;
50 for (
const auto &path : grouped_entries) {
52 if (boost::ends_with(path, target_dataset)) {
67 const std::vector<std::string> exts{
".h5",
".nxs"};
69 "The name of the Nexus file to load");
72 "An output workspace.");
80 g_log.
debug() <<
"Opening file " << filename <<
'\n';
82 ::NeXus::File nxFile(filename);
83 auto entries = nxFile.getEntries();
84 auto itend = entries.end();
87 for (
auto it = entries.begin(); it != itend; ++it) {
88 std::string
name = it->first;
89 std::string type = it->second;
90 nxFile.openGroup(
name, type);
91 auto dataEntries = nxFile.getEntries();
93 for (
auto &dataEntry : dataEntries) {
94 const std::string &dataName = dataEntry.first;
95 const std::string &dataType = dataEntry.second;
96 if (dataName ==
"content_nxs" || dataType !=
"NXdata")
98 g_log.
debug() <<
"Opening " << dataName <<
" " << dataType <<
'\n';
100 nxFile.openGroup(dataName, dataType);
103 auto nxdataEntries = nxFile.getEntries();
104 std::string axis1Name, axis2Name;
105 for (
auto &nxdataEntry : nxdataEntries) {
106 if (nxdataEntry.second ==
"NXparameters")
108 nxFile.openData(nxdataEntry.first);
109 if (nxFile.hasAttr(
"axis")) {
111 nxFile.getAttr(
"axis", axisNo);
113 axis1Name = nxdataEntry.first;
114 else if (axisNo == 2)
115 axis2Name = nxdataEntry.first;
117 throw std::invalid_argument(
"Unknown axis number");
122 std::vector<double> axis1Values, axis2Values;
123 nxFile.readData<
double>(axis1Name, axis1Values);
124 nxFile.readData<
double>(axis2Name, axis2Values);
126 const auto axis1Length = axis1Values.size();
127 const auto axis2Length = axis2Values.size();
128 g_log.
debug() <<
"Axis lengths=" << axis1Length <<
" " << axis2Length <<
'\n';
131 std::vector<double> data;
132 nxFile.readData<
double>(
"data", data);
135 std::vector<double> errors;
137 nxFile.readData<
double>(
"errors", errors);
138 }
catch (::NeXus::Exception &) {
139 g_log.
information() <<
"Field " << dataName <<
" contains no error information.\n";
144 Axis *axis1 = ws->getAxis(0);
145 axis1->
title() = axis1Name;
147 auto lblUnit = std::make_shared<Units::Label>();
148 lblUnit->setLabel(axis1Name,
"");
149 axis1->
unit() = lblUnit;
151 auto axis2 = std::make_unique<NumericAxis>(axis2Length);
152 auto axis2Raw = axis2.get();
153 axis2->title() = axis2Name;
155 lblUnit = std::make_shared<Units::Label>();
156 lblUnit->setLabel(axis2Name,
"");
157 axis2->unit() = lblUnit;
159 ws->setYUnit(axis2Name);
160 ws->replaceAxis(1, std::move(axis2));
162 ws->mutableX(0) = axis1Values;
164 for (
size_t wsIndex = 0; wsIndex < axis2Length; ++wsIndex) {
165 auto &dataY = ws->mutableY(wsIndex);
166 auto &dataE = ws->mutableE(wsIndex);
167 ws->setSharedX(wsIndex, ws->sharedX(0));
169 for (
size_t j = 0; j < axis1Length; ++j) {
172 const size_t fileDataIndex = j * axis2Length + wsIndex;
174 dataY[j] = data[fileDataIndex];
176 dataE[j] = errors[fileDataIndex];
178 axis2Raw->setValue(wsIndex, axis2Values[wsIndex]);
181 outputGroup->addWorkspace(ws);
#define DECLARE_NEXUS_HDF5_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_HDF5_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM mac...
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.
Class to represent the axis of a workspace.
const std::string & title() const
Returns the user-defined title for this axis.
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
@ Load
allowed here which will be passed to the algorithm
Class to hold a set of workspaces.
A property class for workspaces.
LoadMcStasNexus : TODO: DESCRIPTION.
const std::string name() const override
Algorithm's name for identification.
int confidence(Kernel::NexusHDF5Descriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
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 information(const std::string &msg)
Logs at information level.
const std::map< std::string, std::set< std::string > > & getAllEntries() const noexcept
Returns a const reference of the internal map holding all entries in the NeXus HDF5 file.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
@ Output
An output workspace.