Mantid
Loading...
Searching...
No Matches
SaveZODS.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 +
10#include "MantidAPI/Sample.h"
14#include "MantidKernel/System.h"
15
16using namespace Mantid::Kernel;
17using namespace Mantid::API;
18using namespace Mantid::Geometry;
19using namespace Mantid::DataObjects;
20
21namespace Mantid::MDAlgorithms {
22
23// Register the algorithm into the AlgorithmFactory
24DECLARE_ALGORITHM(SaveZODS)
25
26
27const std::string SaveZODS::name() const { return "SaveZODS"; }
28
30int SaveZODS::version() const { return 1; }
31
33const std::string SaveZODS::category() const { return "MDAlgorithms\\DataHandling"; }
34
38 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("InputWorkspace", "", Direction::Input),
39 "An input MDHistoWorkspace in HKL space.");
40
41 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save, ".h5"),
42 "The name of the HDF5 file to write, as a full or relative path.");
43}
44
48 IMDHistoWorkspace_sptr inWS = getProperty("InputWorkspace");
49 std::string Filename = getPropertyValue("Filename");
50 MDHistoWorkspace_sptr ws = std::dynamic_pointer_cast<MDHistoWorkspace>(inWS);
51 if (!ws)
52 throw std::runtime_error("InputWorkspace is not a MDHistoWorkspace");
53 if (ws->getNumDims() != 3)
54 throw std::runtime_error("InputWorkspace must have 3 dimensions (having "
55 "one bin in the 3rd dimension is OK).");
56
57 if (ws->getDimension(0)->getName() != "[H,0,0]")
58 g_log.warning() << "SaveZODS expects the workspace to be in HKL space! "
59 "Saving anyway...\n";
60
61 // Create a HDF5 file
62 auto file = std::make_unique<::NeXus::File>(Filename, NXACC_CREATE5);
63
64 // ----------- Coordinate system -----------
65 uint32_t isLocal = 1;
66 file->makeGroup("CoordinateSystem", "NXgroup", true);
67 file->putAttr("isLocal", isLocal);
68
69 if (ws->getNumExperimentInfo() > 0) {
70 ExperimentInfo_const_sptr ei = ws->getExperimentInfo(0);
71 if (ei) {
72 if (ei->sample().hasOrientedLattice()) {
73 std::vector<double> unitCell;
74 const OrientedLattice &latt = ei->sample().getOrientedLattice();
75 unitCell.emplace_back(latt.a());
76 unitCell.emplace_back(latt.b());
77 unitCell.emplace_back(latt.c());
78 unitCell.emplace_back(latt.alpha());
79 unitCell.emplace_back(latt.beta());
80 unitCell.emplace_back(latt.gamma());
81
82 // Now write out the 6D vector
83 std::vector<int> unit_cell_size(1, 6);
84 file->writeData("unit_cell", unitCell, unit_cell_size);
85 }
86 }
87 }
88
89 file->closeGroup();
90
91 uint64_t numPoints = ws->getNPoints();
92
93 file->makeGroup("Data", "NXgroup", true);
94 file->makeGroup("Data_0", "NXgroup", true);
95
96 // ----------- Attributes ------------------
97 std::vector<double> origin(3, 0.0);
98
99 // Size in each dimension (in the "C" style order, so z,y,x
100 // That is, data[z][y][x] = etc.
101 std::vector<int> size(3, 0);
102
103 // And this will be the "size" field we save, in the usual XYZ order.
104 std::vector<int> size_field(3, 0);
105
106 // Dimension_X attributes give the step size for each dimension
107 for (size_t d = 0; d < 3; d++) {
108 IMDDimension_const_sptr dim = ws->getDimension(d);
109 std::vector<double> direction(3, 0.0);
110 direction[d] = dim->getBinWidth();
111 // Origin of the CENTER of the first bin
112 origin[d] = dim->getMinimum() + dim->getBinWidth() / 2;
113 // Size in each dimension (reverse order for RANK)
114 size[2 - d] = int(dim->getNBins());
115 // Size in each dimension (in the XYZ order)
116 size_field[d] = int(dim->getNBins());
117 file->writeData("direction_" + Strings::toString(d + 1), direction);
118 }
119 file->writeData("origin", origin);
120 file->writeData("size", size_field);
121
122 // Copy data into a vector
123 const auto signal = ws->getSignalArray();
124 std::vector<double> data;
125
126 for (int i = 0; i < size_field[0]; i++)
127 for (int j = 0; j < size_field[1]; j++)
128 for (int k = 0; k < size_field[2]; k++) {
129 int l = i + size_field[0] * j + size_field[0] * size_field[1] * k;
130 data.emplace_back(signal[l]);
131 }
132
133 file->writeData("Data", data, size);
134
135 // Copy errors (not squared) into a vector called sigma
136 const auto errorSquared = ws->getErrorSquaredArray();
137 std::vector<double> sigma;
138 sigma.reserve(numPoints);
139 for (int i = 0; i < size_field[0]; i++)
140 for (int j = 0; j < size_field[1]; j++)
141 for (int k = 0; k < size_field[2]; k++) {
142 int l = i + size_field[0] * j + size_field[0] * size_field[1] * k;
143 sigma.emplace_back(sqrt(errorSquared[l]));
144 }
145 file->writeData("sigma", sigma, size);
146
147 // Close Data_0 group
148 file->closeGroup();
149 // Close Data group
150 file->closeGroup();
151
152 file->close();
153}
154
155} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double sigma
Definition: GetAllEi.cpp:156
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
@ Save
to specify a file to write to, the file may or may not exist
Definition: FileProperty.h:49
A property class for workspaces.
Class to implement UB matrix.
double alpha() const
Get lattice parameter.
Definition: UnitCell.cpp:133
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
Definition: UnitCell.cpp:94
double c() const
Get lattice parameter.
Definition: UnitCell.cpp:128
double beta() const
Get lattice parameter.
Definition: UnitCell.cpp:138
double b() const
Get lattice parameter.
Definition: UnitCell.cpp:123
double gamma() const
Get lattice parameter.
Definition: UnitCell.cpp:143
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
Save a MDHistoWorkspace to a HDF5 format for use with the ZODS analysis software.
Definition: SaveZODS.h:20
void exec() override
Execute the algorithm.
Definition: SaveZODS.cpp:47
void init() override
Initialize the algorithm's properties.
Definition: SaveZODS.cpp:37
const std::string category() const override
Algorithm's category for identification.
Definition: SaveZODS.cpp:33
int version() const override
Algorithm's version for identification.
Definition: SaveZODS.cpp:30
std::shared_ptr< const ExperimentInfo > ExperimentInfo_const_sptr
Shared pointer to const ExperimentInfo.
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
Definition: IMDDimension.h:101
std::string toString(const T &value)
Convert a number to a string.
Definition: Strings.cpp:703
STL namespace.
@ Input
An input workspace.
Definition: Property.h:53