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