Mantid
Loading...
Searching...
No Matches
LoadMcStasNexus.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
14#include "MantidKernel/Unit.h"
16#include "MantidNexus/NexusFile.h"
17
18namespace Mantid::DataHandling {
19using namespace Kernel;
20using namespace API;
21
23
24//----------------------------------------------------------------------------------------------
26const std::string LoadMcStasNexus::name() const { return "LoadMcStasNexus"; }
27
29int LoadMcStasNexus::version() const { return 1; }
30
32const std::string LoadMcStasNexus::category() const { return "DataHandling\\Nexus"; }
33
41 int confidence(0);
42 const auto &entries = descriptor.getAllEntries();
43 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
44 const auto grouped_entries = iter->second;
45 if (std::any_of(grouped_entries.cbegin(), grouped_entries.cend(),
46 [](const auto &address) { return address.ends_with("information"); })) {
47 confidence = 40;
48 break;
49 }
50 }
51 return confidence;
52}
53
54//----------------------------------------------------------------------------------------------
55
56//----------------------------------------------------------------------------------------------
60 const std::vector<std::string> exts{".h5", ".nxs"};
61 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, exts),
62 "The name of the Nexus file to load");
63
64 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputWorkspace", "", Direction::Output),
65 "An output workspace.");
66}
67
68//----------------------------------------------------------------------------------------------
72 std::string filename = getPropertyValue("Filename");
73 g_log.debug() << "Opening file " << filename << '\n';
74
75 Nexus::File nxFile(filename);
76 auto entries = nxFile.getEntries();
77 auto itend = entries.end();
78 WorkspaceGroup_sptr outputGroup(new WorkspaceGroup);
79
80 for (auto it = entries.begin(); it != itend; ++it) {
81 std::string entryName = it->first;
82 std::string type = it->second;
83 nxFile.openGroup(entryName, type);
84 auto dataEntries = nxFile.getEntries();
85
86 for (auto &dataEntry : dataEntries) {
87 const std::string &dataName = dataEntry.first;
88 const std::string &dataType = dataEntry.second;
89 if (dataName == "content_nxs" || dataType != "NXdata")
90 continue;
91 g_log.debug() << "Opening " << dataName << " " << dataType << '\n';
92
93 nxFile.openGroup(dataName, dataType);
94
95 // Find the axis names
96 auto nxdataEntries = nxFile.getEntries();
97 std::string axis1Name, axis2Name;
98 for (const auto &nxdataEntry : nxdataEntries) {
99 if (nxdataEntry.second == "NXparameters")
100 continue;
101 nxFile.openData(nxdataEntry.first);
102 if (nxFile.hasAttr("axis")) {
103 int axisNo(0);
104 nxFile.getAttr("axis", axisNo);
105 if (axisNo == 1)
106 axis1Name = nxdataEntry.first;
107 else if (axisNo == 2)
108 axis2Name = nxdataEntry.first;
109 else
110 throw std::invalid_argument("Unknown axis number");
111 }
112 nxFile.closeData();
113 }
114
115 std::vector<double> axis1Values, axis2Values;
116 nxFile.readData<double>(axis1Name, axis1Values);
117 nxFile.readData<double>(axis2Name, axis2Values);
118
119 const auto axis1Length = axis1Values.size();
120 const auto axis2Length = axis2Values.size();
121 g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length << '\n';
122
123 // Require "data" field
124 std::vector<double> data;
125 nxFile.readData<double>("data", data);
126
127 // Optional errors field
128 std::vector<double> errors;
129 try {
130 nxFile.readData<double>("errors", errors);
131 } catch (Nexus::Exception const &) {
132 g_log.information() << "Field " << dataName << " contains no error information.\n";
133 }
134
136 WorkspaceFactory::Instance().create("Workspace2D", axis2Length, axis1Length, axis1Length);
137 Axis *axis1 = ws->getAxis(0);
138 axis1->title() = axis1Name;
139 // Set caption
140 auto lblUnit = std::make_shared<Units::Label>();
141 lblUnit->setLabel(axis1Name, "");
142 axis1->unit() = lblUnit;
143
144 auto axis2 = std::make_unique<NumericAxis>(axis2Length);
145 auto axis2Raw = axis2.get();
146 axis2->title() = axis2Name;
147 // Set caption
148 lblUnit = std::make_shared<Units::Label>();
149 lblUnit->setLabel(axis2Name, "");
150 axis2->unit() = lblUnit;
151
152 ws->setYUnit(axis2Name);
153 ws->replaceAxis(1, std::move(axis2));
154
155 ws->mutableX(0) = axis1Values;
156
157 for (size_t wsIndex = 0; wsIndex < axis2Length; ++wsIndex) {
158 auto &dataY = ws->mutableY(wsIndex);
159 auto &dataE = ws->mutableE(wsIndex);
160 ws->setSharedX(wsIndex, ws->sharedX(0));
161
162 for (size_t j = 0; j < axis1Length; ++j) {
163 // Data is stored in column-major order so we are translating to
164 // row major for Mantid
165 const size_t fileDataIndex = j * axis2Length + wsIndex;
166
167 dataY[j] = data[fileDataIndex];
168 if (!errors.empty())
169 dataE[j] = errors[fileDataIndex];
170 }
171 axis2Raw->setValue(wsIndex, axis2Values[wsIndex]);
172 }
173 // Make Mantid store the workspace in the group
174 outputGroup->addWorkspace(ws);
175
176 nxFile.closeGroup();
177 }
178 nxFile.closeGroup();
179 }
180
181 setProperty("OutputWorkspace", outputGroup);
182}
183
184} // namespace Mantid::DataHandling
std::string name
Definition Run.cpp:60
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
Class to represent the axis of a workspace.
Definition Axis.h:30
const std::string & title() const
Returns the user-defined title for this axis.
Definition Axis.cpp:20
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
Definition Axis.cpp:28
@ 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.
int confidence(Nexus::NexusDescriptor &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.
Definition Logger.cpp:145
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
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.
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.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
STL namespace.
@ Output
An output workspace.
Definition Property.h:54