Mantid
Loading...
Searching...
No Matches
SaveVTK.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 +
7//---------------------------------------------------
8// Includes
9//---------------------------------------------------
14#include <Poco/File.h>
15#include <fstream>
16#include <string>
17
18namespace Mantid::DataHandling {
19
20// Register algorithm with AlgorithmFactory
21DECLARE_ALGORITHM(SaveVTK)
22
23using namespace Kernel;
24using namespace DataObjects;
25using namespace API;
26
28SaveVTK::SaveVTK() : m_Xmin(0), m_Xmax(0) {}
29
35 // Declare mandatory properties
36 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
37 "The workspace name to use as input");
38 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save),
39 "The name to use when writing the file");
40 // Declare optional properties
41 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
42 mustBePositive->setLower(0.0);
43 declareProperty("Xminimum", 0.0, mustBePositive,
44 "No bin that contains x values lower than this will be saved (default\n"
45 "0)");
46 declareProperty("Xmaximum", 0.0, mustBePositive,
47 "No bin that contains x values higher than this will saved (default\n"
48 "0 signifies the highest x value)");
49}
50
56 std::string filename = getProperty("Filename");
57 g_log.debug() << "Parameters: Filename='" << filename << "'\n";
58 // add extension
59 filename += ".vtu";
60
61 MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
62 if (!inputWorkspace) {
63 g_log.error("Failed to retrieve inputWorkspace.");
64 throw Exception::NullPointerException("SaveVTK::exec()", "inputWorkspace");
65 }
66
68
69 // Open file for writing
70 std::ofstream outVTP(filename.c_str());
71 if (!outVTP) {
72 g_log.error("Failed to open file: " + filename);
73 throw Exception::FileError("Failed to open file ", filename);
74 }
75
76 // First write document level XML header
77 outVTP << "<?xml version=\"1.0\"?>\n"
78 "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
79 "byte_order=\"LittleEndian\">\n"
80 "<UnstructuredGrid>\n";
81
82 const std::string workspaceID = inputWorkspace->id();
83 if (workspaceID.find("Workspace2D") != std::string::npos) {
84 const Workspace2D_sptr localWorkspace = std::dynamic_pointer_cast<Workspace2D>(inputWorkspace);
85
86 // Write out whole range
87 bool xMin(m_Xmin > 0.0), xMax(m_Xmax > 0.0);
88 Progress prog(this, 0.0, 1.0, 97);
89 if (!xMin && !xMax) {
90 for (int hNum = 2; hNum < 100; ++hNum) {
91 writeVTKPiece(outVTP, localWorkspace->x(hNum).rawData(), localWorkspace->y(hNum).rawData(),
92 localWorkspace->e(hNum).rawData(), hNum);
93 prog.report();
94 }
95 } else {
96 for (int hNum = 2; hNum < 100; ++hNum) {
97
98 auto &X = localWorkspace->x(hNum);
99 auto &Y = localWorkspace->y(hNum);
100 auto &E = localWorkspace->e(hNum);
101
102 std::vector<double> xValue, yValue, errors;
103 std::vector<double>::size_type nVals(Y.size());
104
105 for (int i = 0; i < static_cast<int>(nVals); ++i) {
106
107 if (xMin && X[i] < m_Xmin) {
108 continue;
109 }
110
111 if (xMax && X[i + 1] > m_Xmax) {
112 xValue.emplace_back(X[i]);
113 break;
114 }
115
116 xValue.emplace_back(X[i]);
117 if (i == static_cast<int>(nVals) - 1) {
118 xValue.emplace_back(X[i + 1]);
119 }
120
121 yValue.emplace_back(Y[i]);
122 errors.emplace_back(E[i]);
123 }
124 // sanity check
125 assert((int)xValue.size() == (int)yValue.size() + 1);
126
127 writeVTKPiece(outVTP, xValue, yValue, errors, hNum);
128 prog.report();
129 }
130 }
131 } else {
132 outVTP.close();
133 Poco::File(filename).remove();
134 throw Exception::NotImplementedError("SaveVTK only implemented for Workspace2D\n");
135 }
136
137 // Final XML end block tags
138 outVTP << "</UnstructuredGrid>\n</VTKFile>\n";
139 outVTP.close();
140}
141
146 m_Xmin = getProperty("Xminimum");
147 m_Xmax = getProperty("Xmaximum");
148
149 if (m_Xmin > 0. && m_Xmax > 0 && m_Xmin > m_Xmax) {
150 g_log.error("Invalid range specification.");
151 throw std::invalid_argument("SaveVTK: Inconsistent range values");
152 }
153}
154
163void SaveVTK::writeVTKPiece(std::ostream &outVTP, const std::vector<double> &xValue, const std::vector<double> &yValue,
164 const std::vector<double> &errors, int index) const {
165 (void)errors; // Avoid compiler warning
166
167 auto nY = static_cast<int>(yValue.size());
168 int nPoints(8 * nY);
169 outVTP << "<Piece NumberOfPoints=\"" << nPoints << "\" NumberOfCells=\"" << nY << "\">";
170 outVTP << "<CellData Scalars=\"counts\">"
171 << "<DataArray type=\"Float32\" Name=\"counts\" "
172 "NumberOfComponents=\"1\" format=\"ascii\">\n";
173 for (int i = 0; i < nY; ++i) {
174 outVTP << yValue[i] << "\n";
175 }
176 outVTP << "</DataArray></CellData>\n";
177
178 outVTP << "<Points>"
179 << "<DataArray type=\"Float32\" NumberOfComponents=\"3\" "
180 "format=\"ascii\">\n";
181
182 double deltaZ(100.);
183 for (int i = 0; i < nY; ++i) {
184 // first face
185 double xLow(xValue[i]), xUpp(xValue[i + 1]), ypos(yValue[i]), zpos(-index * deltaZ);
186 outVTP << xLow << " " << 0.0 << " " << zpos << "\n";
187 outVTP << xUpp << " " << 0.0 << " " << zpos << "\n";
188 outVTP << xLow << " " << ypos << " " << zpos << "\n";
189 outVTP << xUpp << " " << ypos << " " << zpos << "\n";
190 // second face
191 zpos = -(index + 1) * deltaZ;
192 outVTP << xLow << " " << 0.0 << " " << zpos << "\n";
193 outVTP << xUpp << " " << 0.0 << " " << zpos << "\n";
194 outVTP << xLow << " " << ypos << " " << zpos << "\n";
195 outVTP << xUpp << " " << ypos << " " << zpos << "\n";
196 }
197 outVTP << "</DataArray></Points>\n";
198 outVTP << "<Cells>\n"
199 << "<DataArray type=\"Int32\" Name =\"connectivity\" format=\"ascii\">\n";
200 for (int i = 0; i < nPoints; ++i) {
201 outVTP << i << "\n";
202 }
203 outVTP << "</DataArray>\n";
204 outVTP << "<DataArray type=\"Int32\" Name =\"offsets\" format=\"ascii\">\n";
205 for (int i = 8; i <= nPoints; i += 8) {
206 outVTP << i << "\n";
207 }
208 outVTP << "</DataArray>\n";
209 outVTP << "<DataArray type=\"UInt8\" Name =\"types\" format=\"ascii\">\n";
210 for (int i = 0; i < nPoints; ++i) {
211 outVTP << "11\n";
212 }
213 outVTP << "</DataArray>\n";
214
215 outVTP << "</Cells>\n";
216 // End of this piece
217 outVTP << "</Piece>\n";
218}
219} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
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
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
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
void writeVTKPiece(std::ostream &outVTP, const std::vector< double > &xValue, const std::vector< double > &yValue, const std::vector< double > &errors, int index) const
Write a histogram to the file.
Definition: SaveVTK.cpp:163
double m_Xmin
The x-axis minimum.
Definition: SaveVTK.h:77
void checkOptionalProperties()
Check the optional properties.
Definition: SaveVTK.cpp:145
SaveVTK()
Default constructor.
Definition: SaveVTK.cpp:28
void exec() override
Override virtual exec function.
Definition: SaveVTK.cpp:55
double m_Xmax
The x-axis minimum.
Definition: SaveVTK.h:80
void init() override
Override virtual init function.
Definition: SaveVTK.cpp:34
Records the filename and the description of failure.
Definition: Exception.h:98
Marks code as not implemented yet.
Definition: Exception.h:138
Exception thrown when an attempt is made to dereference a null pointer.
Definition: Exception.h:305
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
@ Input
An input workspace.
Definition: Property.h:53