Mantid
Loading...
Searching...
No Matches
NexusFileIO.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// NexusFileIO
8// @author Ronald Fowler
9#include <sstream>
10#include <vector>
11
12#ifdef _WIN32
13#include <io.h>
14// Define the MAX_NAME macro for Windows
15// Maximum base file name size on modern windows systems is 260 characters
16#define NAME_MAX 260
17#endif /* _WIN32 */
26#include "MantidKernel/Unit.h"
30
31#include <Poco/File.h>
32#include <Poco/Path.h>
33
34namespace Mantid::NeXus {
35using namespace Kernel;
36using namespace API;
37using namespace DataObjects;
38
39namespace {
41Logger g_log("NexusFileIO");
42} // namespace
43
46 : fileID(), m_filehandle(), m_nexuscompression(NX_COMP_LZW), m_progress(nullptr), m_filename() {}
47
50 : fileID(), m_filehandle(), m_nexuscompression(NX_COMP_LZW), m_progress(prog), m_filename() {}
51
53
54//
55// Write out the data in a worksvn space in Nexus "Processed" format.
56// This *Proposed* standard comprises the fields:
57// <NXentry name="{Name of entry}">
58// <title>
59// {Extended title for entry}
60// </title>
61// <definition
62// URL="http://www.nexusformat.org/instruments/xml/NXprocessed.xml"
63// version="1.0">
64// NXprocessed
65// </definition>
66// <NXsample name="{Name of sample}">?
67// {Any relevant sample information necessary to define the data.}
68// </NXsample>
69// <NXdata name="{Name of processed data}">
70// <values signal="1" type="NX_FLOAT[:,:]" axes="axis1:axis2">{Processed
71// values}</values>
72// <axis1 type="NX_FLOAT[:]">{Values of the first dimension's axis}</axis1>
73// <axis2 type="NX_FLOAT[:]">{Values of the second dimension's axis}</axis2>
74// </NXdata>
75// <NXprocess name="{Name of process}">?
76// {Any relevant information about the steps used to process the data.}
77// </NXprocess>
78// </NXentry>
79
80void NexusFileIO::openNexusWrite(const std::string &fileName, NexusFileIO::optional_size_t entryNumber,
81 const bool append_to_file) {
82 // open named file and entry - file may exist
83 // @throw Exception::FileError if cannot open Nexus file for writing
84 //
85 NXaccess mode(NXACC_CREATE5);
86 std::string mantidEntryName;
87 m_filename = fileName;
88 //
89 // If file to write exists, then open as is else see if the extension is xml,
90 // if so open as xml
91 // format otherwise as compressed hdf5
92 //
93 if ((Poco::File(m_filename).exists() && append_to_file) || m_filehandle)
94 mode = NXACC_RDWR;
95
96 else {
97 if (fileName.find(".xml") < fileName.size() || fileName.find(".XML") < fileName.size()) {
98 mode = NXACC_CREATEXML;
99 m_nexuscompression = NX_COMP_NONE;
100 }
101 mantidEntryName = "mantid_workspace_1";
102 }
103
104 /*Only create the file handle if needed.*/
105 if (!m_filehandle) {
106 // The nexus or HDF5 libraries crash when the filename is greater than 255
107 // on OSX and Ubuntu.
108 Poco::Path path(fileName);
109 std::string baseName = path.getBaseName();
110 if (baseName.size() > NAME_MAX) {
111 std::string message = "Filename is too long. Unable to open file: ";
112 throw Exception::FileError(message, fileName);
113 }
114
115 // open the file and copy the handle into the NeXus::File object
116 NXstatus status = NXopen(fileName.c_str(), mode, &fileID);
117 if (status == NX_ERROR) {
118 g_log.error("Unable to open file " + fileName);
119 throw Exception::FileError("Unable to open File:", fileName);
120 }
121 auto file = new ::NeXus::File(fileID, true);
122 // clang-format off
123 m_filehandle = std::shared_ptr< ::NeXus::File>(file);
124 // clang-format on
125 }
126
127 //
128 // for existing files, search for any current mantid_workspace_<n> entries and
129 // set the
130 // new name to be n+1 so that we do not over-write by default. This may need
131 // changing.
132 //
133 if (mode == NXACC_RDWR) {
134 size_t count = 0;
135 if (entryNumber.is_initialized()) {
136 // Use the entry number provided.
137 count = entryNumber.get();
138 } else {
139 // Have to figure it our ourselves. Requires opening the exisitng file to
140 // get the information via a search.
142 }
143
144 std::stringstream suffix;
145 suffix << (count + 1);
146 mantidEntryName = "mantid_workspace_" + suffix.str();
147 }
148 //
149 // make and open the new mantid_workspace_<n> group
150 // file remains open until explicit close
151 //
152 const std::string className = "NXentry";
153
154 m_filehandle->makeGroup(mantidEntryName, className);
155 m_filehandle->openGroup(mantidEntryName, className);
156}
157
158void NexusFileIO::closeGroup() { m_filehandle->closeGroup(); }
159
160//-----------------------------------------------------------------------------------------------
162 if (m_filehandle) {
163 m_filehandle.reset();
164 }
165}
166
167//-----------------------------------------------------------------------------------------------
176int NexusFileIO::writeNexusProcessedHeader(const std::string &title, const std::string &wsName) const {
177
178 const std::string className = "Mantid Processed Workspace";
179 std::vector<std::string> attributes, avalues;
180 attributes.reserve(2);
181 avalues.reserve(2);
182 if (!writeNxValue<std::string>("title", title, NX_CHAR, attributes, avalues))
183 return (3);
184
185 // name for workspace if this is a multi workspace nexus file
186 if (!wsName.empty()) {
187 if (!writeNxValue<std::string>("workspace_name", wsName, NX_CHAR, attributes, avalues))
188 return (3);
189 }
190
191 attributes.emplace_back("URL");
192 avalues.emplace_back("http://www.nexusformat.org/instruments/xml/NXprocessed.xml");
193 attributes.emplace_back("Version");
194 avalues.emplace_back("1.0");
195 // this may not be the "correct" long term path, but it is valid at present
196 if (!writeNxValue<std::string>("definition", className, NX_CHAR, attributes, avalues))
197 return (3);
198 avalues.clear();
199 avalues.emplace_back("http://www.isis.rl.ac.uk/xml/IXmantid.xml");
200 avalues.emplace_back("1.0");
201 if (!writeNxValue<std::string>("definition_local", className, NX_CHAR, attributes, avalues))
202 return (3);
203 return (0);
204}
205
206//-----------------------------------------------------------------------------------------------
207//
208// write an NXdata entry with Float array values
209//
210void NexusFileIO::writeNxFloatArray(const std::string &name, const std::vector<double> &values,
211 const std::vector<std::string> &attributes,
212 const std::vector<std::string> &avalues) const {
213 m_filehandle->writeData(name, values);
214 m_filehandle->openData(name);
215 for (size_t it = 0; it < attributes.size(); ++it)
216 m_filehandle->putAttr(attributes[it], avalues[it]);
217 m_filehandle->closeData();
218}
219
220//-----------------------------------------------------------------------------------------------
221//
222// write an NXdata entry with String array values
223//
224bool NexusFileIO::writeNxStringArray(const std::string &name, const std::vector<std::string> &values,
225 const std::vector<std::string> &attributes,
226 const std::vector<std::string> &avalues) const {
227 int dimensions[2];
228 const auto maxlen = std::max_element(values.cbegin(), values.cend(),
229 [](const auto &lhs, const auto &rhs) { return lhs.size() < rhs.size(); });
230 dimensions[0] = static_cast<int>(values.size());
231 dimensions[1] = static_cast<int>(maxlen->size());
232 NXstatus status = NXmakedata(fileID, name.c_str(), NX_CHAR, 2, dimensions);
233 if (status == NX_ERROR)
234 return (false);
235 NXopendata(fileID, name.c_str());
236 for (size_t it = 0; it < attributes.size(); ++it)
237 NXputattr(fileID, attributes[it].c_str(), avalues[it].c_str(), static_cast<int>(avalues[it].size() + 1), NX_CHAR);
238 auto strs = new char[values.size() * maxlen->size()];
239 for (size_t i = 0; i < values.size(); i++) {
240 strncpy(&strs[i * maxlen->size()], values[i].c_str(), maxlen->size());
241 }
242 NXputdata(fileID, strs);
243 NXclosedata(fileID);
244 delete[] strs;
245 return (true);
246}
247//
248// Write an NXnote entry with data giving parameter pair values for algorithm
249// history and environment
250// Use NX_CHAR instead of NX_BINARY for the parameter values to make more
251// simple.
252//
253bool NexusFileIO::writeNxNote(const std::string &noteName, const std::string &author, const std::string &date,
254 const std::string &description, const std::string &pairValues) const {
255 m_filehandle->makeGroup(noteName, "NXnote", true);
256
257 std::vector<std::string> attributes, avalues;
258 if (!date.empty()) {
259 attributes.emplace_back("date");
260 avalues.emplace_back(date);
261 }
262 if (!writeNxValue<std::string>("author", author, NX_CHAR, attributes, avalues))
263 return (false);
264 attributes.clear();
265 avalues.clear();
266
267 if (!writeNxValue<std::string>("description", description, NX_CHAR, attributes, avalues))
268 return (false);
269 if (!writeNxValue<std::string>("data", pairValues, NX_CHAR, attributes, avalues))
270 return (false);
271
272 m_filehandle->closeGroup();
273 return (true);
274}
275
276//-------------------------------------------------------------------------------------
281 const bool &uniformSpectra, const std::vector<int> &indices,
282 const char *group_name, bool write2Ddata) const {
283 NXstatus status;
284
285 // write data entry
286 status = NXmakegroup(fileID, group_name, "NXdata");
287 if (status == NX_ERROR)
288 return (2);
289 NXopengroup(fileID, group_name, "NXdata");
290 // write workspace data
291 const size_t nHist = localworkspace->getNumberHistograms();
292 if (nHist < 1)
293 return (2);
294 const size_t nSpectBins = localworkspace->y(0).size();
295 const size_t nSpect = indices.size();
296 int dims_array[2] = {static_cast<int>(nSpect), static_cast<int>(nSpectBins)};
297
298 // Set the axis labels and values
299 Mantid::API::Axis *xAxis = localworkspace->getAxis(0);
300 Mantid::API::Axis *sAxis = localworkspace->getAxis(1);
301 std::string xLabel, sLabel;
302 if (xAxis->isSpectra())
303 xLabel = "spectraNumber";
304 else {
305 if (xAxis->unit())
306 xLabel = xAxis->unit()->unitID();
307 else
308 xLabel = "unknown";
309 }
310 if (sAxis->isSpectra())
311 sLabel = "spectraNumber";
312 else {
313 if (sAxis->unit())
314 sLabel = sAxis->unit()->unitID();
315 else
316 sLabel = "unknown";
317 }
318 // Get the values on the vertical axis
319 std::vector<double> axis2;
320 if (nSpect < nHist)
321 for (size_t i = 0; i < nSpect; i++)
322 axis2.emplace_back((*sAxis)(indices[i]));
323 else
324 for (size_t i = 0; i < sAxis->length(); i++)
325 axis2.emplace_back((*sAxis)(i));
326
327 int start[2] = {0, 0};
328 int asize[2] = {1, dims_array[1]};
329
330 // -------------- Actually write the 2D data ----------------------------
331 if (write2Ddata) {
332 std::string name = "values";
333 NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize);
334 NXopendata(fileID, name.c_str());
335 for (size_t i = 0; i < nSpect; i++) {
336 NXputslab(fileID, localworkspace->y(indices[i]).rawData().data(), start, asize);
337 start[0]++;
338 }
339 if (m_progress != nullptr)
340 m_progress->reportIncrement(1, "Writing data");
341 int signal = 1;
342 NXputattr(fileID, "signal", &signal, 1, NX_INT32);
343 // More properties
344 const std::string axesNames = "axis2,axis1";
345 NXputattr(fileID, "axes", axesNames.c_str(), static_cast<int>(axesNames.size()), NX_CHAR);
346 std::string yUnits = localworkspace->YUnit();
347 std::string yUnitLabel = localworkspace->YUnitLabel();
348 NXputattr(fileID, "units", yUnits.c_str(), static_cast<int>(yUnits.size()), NX_CHAR);
349 NXputattr(fileID, "unit_label", yUnitLabel.c_str(), static_cast<int>(yUnitLabel.size()), NX_CHAR);
350 NXclosedata(fileID);
351
352 // error
353 name = "errors";
354 NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize);
355 NXopendata(fileID, name.c_str());
356 start[0] = 0;
357 for (size_t i = 0; i < nSpect; i++) {
358 NXputslab(fileID, localworkspace->e(indices[i]).rawData().data(), start, asize);
359 start[0]++;
360 }
361
362 if (m_progress != nullptr)
363 m_progress->reportIncrement(1, "Writing data");
364
365 // Fractional area for RebinnedOutput
366 if (localworkspace->id() == "RebinnedOutput") {
367 RebinnedOutput_const_sptr rebin_workspace = std::dynamic_pointer_cast<const RebinnedOutput>(localworkspace);
368 name = "frac_area";
369 NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize);
370 NXopendata(fileID, name.c_str());
371 start[0] = 0;
372 for (size_t i = 0; i < nSpect; i++) {
373 NXputslab(fileID, rebin_workspace->readF(indices[i]).data(), start, asize);
374 start[0]++;
375 }
376
377 std::string finalized = (rebin_workspace->isFinalized()) ? "1" : "0";
378 NXputattr(fileID, "finalized", finalized.c_str(), 2, NX_CHAR);
379 std::string sqrdErrs = (rebin_workspace->hasSqrdErrors()) ? "1" : "0";
380 NXputattr(fileID, "sqrd_errors", sqrdErrs.c_str(), 2, NX_CHAR);
381
382 if (m_progress != nullptr)
383 m_progress->reportIncrement(1, "Writing data");
384 }
385
386 // Potentially x error
387 if (localworkspace->hasDx(0)) {
388 dims_array[0] = static_cast<int>(nSpect);
389 dims_array[1] = static_cast<int>(localworkspace->dx(0).size());
390 std::string dxErrorName = "xerrors";
391 NXcompmakedata(fileID, dxErrorName.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize);
392 NXopendata(fileID, dxErrorName.c_str());
393 start[0] = 0;
394 asize[1] = dims_array[1];
395 for (size_t i = 0; i < nSpect; i++) {
396
397 NXputslab(fileID, localworkspace->dx(indices[i]).rawData().data(), start, asize);
398 start[0]++;
399 }
400 }
401
402 NXclosedata(fileID);
403 }
404
405 // write X data, as single array or all values if "ragged"
406 if (uniformSpectra) {
407 dims_array[0] = static_cast<int>(localworkspace->x(0).size());
408 NXmakedata(fileID, "axis1", NX_FLOAT64, 1, dims_array);
409 NXopendata(fileID, "axis1");
410 NXputdata(fileID, localworkspace->x(0).rawData().data());
411
412 } else {
413 dims_array[0] = static_cast<int>(nSpect);
414 dims_array[1] = static_cast<int>(localworkspace->x(0).size());
415 NXmakedata(fileID, "axis1", NX_FLOAT64, 2, dims_array);
416 NXopendata(fileID, "axis1");
417 start[0] = 0;
418 asize[1] = dims_array[1];
419 for (size_t i = 0; i < nSpect; i++) {
420 NXputslab(fileID, localworkspace->x(indices[i]).rawData().data(), start, asize);
421 start[0]++;
422 }
423 }
424
425 std::string dist = (localworkspace->isDistribution()) ? "1" : "0";
426 NXputattr(fileID, "distribution", dist.c_str(), 2, NX_CHAR);
427 NXputattr(fileID, "units", xLabel.c_str(), static_cast<int>(xLabel.size()), NX_CHAR);
428
429 auto label = std::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(xAxis->unit());
430 if (label) {
431 NXputattr(fileID, "caption", label->caption().c_str(), static_cast<int>(label->caption().size()), NX_CHAR);
432 auto unitLbl = label->label();
433 NXputattr(fileID, "label", unitLbl.ascii().c_str(), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
434 }
435
436 NXclosedata(fileID);
437
438 if (!sAxis->isText()) {
439 // write axis2, maybe just spectra number
440 dims_array[0] = static_cast<int>(axis2.size());
441 NXmakedata(fileID, "axis2", NX_FLOAT64, 1, dims_array);
442 NXopendata(fileID, "axis2");
443 NXputdata(fileID, axis2.data());
444 NXputattr(fileID, "units", sLabel.c_str(), static_cast<int>(sLabel.size()), NX_CHAR);
445
446 auto unitLabel = std::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit());
447 if (unitLabel) {
448 NXputattr(fileID, "caption", unitLabel->caption().c_str(), static_cast<int>(unitLabel->caption().size()),
449 NX_CHAR);
450 auto unitLbl = unitLabel->label();
451 NXputattr(fileID, "label", unitLbl.ascii().c_str(), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
452 }
453
454 NXclosedata(fileID);
455 } else {
456 std::string textAxis;
457 for (size_t i = 0; i < sAxis->length(); i++) {
458 textAxis += sAxis->label(i) + "\n";
459 }
460 dims_array[0] = static_cast<int>(textAxis.size());
461 NXmakedata(fileID, "axis2", NX_CHAR, 1, dims_array);
462 NXopendata(fileID, "axis2");
463 NXputdata(fileID, textAxis.c_str());
464 NXputattr(fileID, "units", "TextAxis", 8, NX_CHAR);
465
466 auto unitLabel = std::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit());
467 if (unitLabel) {
468 NXputattr(fileID, "caption", unitLabel->caption().c_str(), static_cast<int>(unitLabel->caption().size()),
469 NX_CHAR);
470 auto unitLbl = unitLabel->label();
471 NXputattr(fileID, "label", unitLbl.ascii().c_str(), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
472 }
473
474 NXclosedata(fileID);
475 }
476
477 writeNexusBinMasking(localworkspace);
478
479 status = NXclosegroup(fileID);
480 return ((status == NX_ERROR) ? 3 : 0);
481}
482
483//-------------------------------------------------------------------------------------
492template <typename ColumnT, typename NexusT>
493void NexusFileIO::writeTableColumn(int type, const std::string &interpret_as, const API::Column &col,
494 const std::string &columnName) const {
495 const auto nRows = static_cast<int>(col.size());
496 int dims_array[1] = {nRows};
497
498 auto toNexus = new NexusT[nRows];
499 for (int ii = 0; ii < nRows; ii++)
500 toNexus[ii] = static_cast<NexusT>(col.cell<ColumnT>(ii));
501 NXwritedata(columnName.c_str(), type, 1, dims_array, toNexus, false);
502 delete[] toNexus;
503
504 // attributes
505 NXopendata(fileID, columnName.c_str());
506 std::string units = "Not known";
507 NXputattr(fileID, "units", units.c_str(), static_cast<int>(units.size()), NX_CHAR);
508 NXputattr(fileID, "interpret_as", interpret_as.c_str(), static_cast<int>(interpret_as.size()), NX_CHAR);
509 NXclosedata(fileID);
510}
511
512// Helper templated definitions
513namespace {
514
515// Get a size of a vector to be used in writeNexusVectorColumn(...)
516template <typename VecType> size_t getSizeOf(const VecType &vec) { return vec.size(); }
517
518// Special case of V3D
519size_t getSizeOf(const Kernel::V3D & /*unused*/) { return 3; }
520} // namespace
521
529template <typename VecType, typename ElemType>
530void NexusFileIO::writeNexusVectorColumn(const Column_const_sptr &col, const std::string &columnName, int nexusType,
531 const std::string &interpret_as) const {
532 ConstColumnVector<VecType> column(col);
533 size_t rowCount = column.size();
534
535 // Search for the longest array amongst the cells
536 size_t maxSize(0);
537 for (size_t i = 0; i < rowCount; ++i) {
538 size_t size = getSizeOf(column[i]);
539
540 if (size > maxSize)
541 maxSize = size;
542 }
543
544 // Set-up dimensions
545 int dims[2]{static_cast<int>(rowCount), static_cast<int>(maxSize)};
546
547 // Create data array
548 boost::scoped_array<ElemType> data(new ElemType[rowCount * maxSize]);
549
550 for (size_t i = 0; i < rowCount; ++i) {
551 // copy data in a cell to a vector with the same element type
552 std::vector<ElemType> values = column[i];
553
554 // So that all the arrays are of the size maxSize
555 values.resize(maxSize);
556
557 // Copy values to the data array
558 for (size_t j = 0; j < maxSize; ++j)
559 data[i * maxSize + j] = values[j];
560 }
561
562 // Write data
563 NXwritedata(columnName.c_str(), nexusType, 2, dims, data.get(), false);
564
565 NXopendata(fileID, columnName.c_str());
566
567 // Add sizes of rows as attributes. We can't use padding zeroes to determine
568 // that because the
569 // vector stored might end with zeroes as well.
570 for (size_t i = 0; i < rowCount; ++i) {
571 auto size = static_cast<int>(getSizeOf(column[i]));
572
573 std::ostringstream rowSizeAttrName;
574 rowSizeAttrName << "row_size_" << i;
575
576 NXputattr(fileID, rowSizeAttrName.str().c_str(), &size, 1, NX_INT32);
577 }
578
579 std::string units = "Not known";
580
581 // Write general attributes
582 NXputattr(fileID, "units", units.c_str(), static_cast<int>(units.size()), NX_CHAR);
583 NXputattr(fileID, "interpret_as", interpret_as.c_str(), static_cast<int>(interpret_as.size()), NX_CHAR);
584
585 NXclosedata(fileID);
586}
587//-------------------------------------------------------------------------------------
591 const char *group_name) const {
592 NXstatus status = NX_ERROR;
593
594 std::shared_ptr<const TableWorkspace> tableworkspace =
595 std::dynamic_pointer_cast<const TableWorkspace>(itableworkspace);
596 std::shared_ptr<const PeaksWorkspace> peakworkspace =
597 std::dynamic_pointer_cast<const PeaksWorkspace>(itableworkspace);
598
599 if (!tableworkspace && !peakworkspace)
600 return 3;
601
602 // write data entry
603 status = NXmakegroup(fileID, group_name, "NXdata");
604 if (status == NX_ERROR)
605 return (2);
606 NXopengroup(fileID, group_name, "NXdata");
607
608 auto nRows = static_cast<int>(itableworkspace->rowCount());
609
610 for (size_t i = 0; i < itableworkspace->columnCount(); i++) {
611 Column_const_sptr col = itableworkspace->getColumn(i);
612
613 std::string str = "column_" + std::to_string(i + 1);
614
615 if (col->isType<double>()) {
616 writeTableColumn<double, double>(NX_FLOAT64, "", *col, str);
617 } else if (col->isType<float>()) {
618 writeTableColumn<float, float>(NX_FLOAT32, "", *col, str);
619 } else if (col->isType<int>()) {
620 writeTableColumn<int, int32_t>(NX_INT32, "", *col, str);
621 } else if (col->isType<uint32_t>()) {
622 writeTableColumn<uint32_t, uint32_t>(NX_UINT32, "", *col, str);
623 } else if (col->isType<int64_t>()) {
624 writeTableColumn<int64_t, int64_t>(NX_INT64, "", *col, str);
625 } else if (col->isType<size_t>()) {
626 writeTableColumn<size_t, uint64_t>(NX_UINT64, "", *col, str);
627 } else if (col->isType<Boolean>()) {
628 writeTableColumn<bool, bool>(NX_UINT8, "", *col, str);
629 } else if (col->isType<std::string>()) {
630 // determine max string size
631 size_t maxStr = 0;
632 for (int ii = 0; ii < nRows; ii++) {
633 if (col->cell<std::string>(ii).size() > maxStr)
634 maxStr = col->cell<std::string>(ii).size();
635 }
636 // If the column is empty fill the data with spaces.
637 // Strings containing spaces only will be read back in as empty strings.
638 if (maxStr == 0) {
639 maxStr = 1;
640 }
641 int dims_array[2] = {nRows, static_cast<int>(maxStr)};
642 int asize[2] = {1, dims_array[1]};
643
644 NXcompmakedata(fileID, str.c_str(), NX_CHAR, 2, dims_array, false, asize);
645 NXopendata(fileID, str.c_str());
646 auto toNexus = new char[maxStr * nRows];
647 for (int ii = 0; ii < nRows; ii++) {
648 std::string rowStr = col->cell<std::string>(ii);
649 for (size_t ic = 0; ic < rowStr.size(); ic++)
650 toNexus[ii * maxStr + ic] = rowStr[ic];
651 for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxStr); ic++)
652 toNexus[ii * maxStr + ic] = ' ';
653 }
654
655 NXputdata(fileID, toNexus);
656 delete[] toNexus;
657
658 // attributes
659 std::string units = "N/A";
660 std::string interpret_as = "A string";
661 NXputattr(fileID, "units", units.c_str(), static_cast<int>(units.size()), NX_CHAR);
662 NXputattr(fileID, "interpret_as", interpret_as.c_str(), static_cast<int>(interpret_as.size()), NX_CHAR);
663
664 NXclosedata(fileID);
665 } else if (col->isType<std::vector<int>>()) {
666 writeNexusVectorColumn<std::vector<int>, int>(col, str, NX_INT32, "");
667 } else if (col->isType<std::vector<double>>()) {
668 writeNexusVectorColumn<std::vector<double>, double>(col, str, NX_FLOAT64, "");
669 } else if (col->isType<Kernel::V3D>()) {
670 writeNexusVectorColumn<Kernel::V3D, double>(col, str, NX_FLOAT64, "V3D");
671 }
672
673 // write out title
674 NXopendata(fileID, str.c_str());
675 NXputattr(fileID, "name", col->name().c_str(), static_cast<int>(col->name().size()), NX_CHAR);
676 NXclosedata(fileID);
677 }
678
679 status = NXclosegroup(fileID);
680 return ((status == NX_ERROR) ? 3 : 0);
681}
682
683//-------------------------------------------------------------------------------------
695 std::vector<int64_t> &indices, double *tofs, float *weights,
696 float *errorSquareds, int64_t *pulsetimes, bool compress) const {
697 NXopengroup(fileID, "event_workspace", "NXdata");
698
699 // The array of indices for each event list #
700 int dims_array[1] = {static_cast<int>(indices.size())};
701 if (!indices.empty()) {
702 if (compress)
703 NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array);
704 else
705 NXmakedata(fileID, "indices", NX_INT64, 1, dims_array);
706 NXopendata(fileID, "indices");
707 NXputdata(fileID, indices.data());
708 std::string yUnits = ws->YUnit();
709 std::string yUnitLabel = ws->YUnitLabel();
710 NXputattr(fileID, "units", yUnits.c_str(), static_cast<int>(yUnits.size()), NX_CHAR);
711 NXputattr(fileID, "unit_label", yUnitLabel.c_str(), static_cast<int>(yUnitLabel.size()), NX_CHAR);
712 NXclosedata(fileID);
713 }
714
715 // Write out each field
716 dims_array[0] = static_cast<int>(indices.back()); // TODO big truncation error! This is the # of events
717 if (tofs)
718 NXwritedata("tof", NX_FLOAT64, 1, dims_array, tofs, compress);
719 if (pulsetimes)
720 NXwritedata("pulsetime", NX_INT64, 1, dims_array, pulsetimes, compress);
721 if (weights)
722 NXwritedata("weight", NX_FLOAT32, 1, dims_array, weights, compress);
723 if (errorSquareds)
724 NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, errorSquareds, compress);
725
726 // Close up the overall group
727 NXstatus status = NXclosegroup(fileID);
728 return ((status == NX_ERROR) ? 3 : 0);
729}
730
731//-------------------------------------------------------------------------------------
735 // write data entry
736 NXstatus status = NXmakegroup(fileID, "event_workspace", "NXdata");
737 if (status == NX_ERROR)
738 return (2);
739 NXopengroup(fileID, "event_workspace", "NXdata");
740
741 for (size_t wi = 0; wi < ws->getNumberHistograms(); wi++) {
742 std::ostringstream group_name;
743 group_name << "event_list_" << wi;
744 this->writeEventList(ws->getSpectrum(wi), group_name.str());
745 }
746
747 // Close up the overall group
748 status = NXclosegroup(fileID);
749 return ((status == NX_ERROR) ? 3 : 0);
750}
751
752//-------------------------------------------------------------------------------------
754void NexusFileIO::NXwritedata(const char *name, int datatype, int rank, int *dims_array, void *data,
755 bool compress) const {
756 if (compress) {
757 // We'll use the same slab/buffer size as the size of the array
758 NXcompmakedata(fileID, name, datatype, rank, dims_array, m_nexuscompression, dims_array);
759 } else {
760 // Write uncompressed.
761 NXmakedata(fileID, name, datatype, rank, dims_array);
762 }
763
764 NXopendata(fileID, name);
765 NXputdata(fileID, data);
766 NXclosedata(fileID);
767}
768
769//-------------------------------------------------------------------------------------
777template <class T>
778void NexusFileIO::writeEventListData(std::vector<T> events, bool writeTOF, bool writePulsetime, bool writeWeight,
779 bool writeError) const {
780 // Do nothing if there are no events.
781 if (events.empty())
782 return;
783
784 size_t num = events.size();
785 auto tofs = new double[num];
786 auto weights = new double[num];
787 auto errorSquareds = new double[num];
788 auto pulsetimes = new int64_t[num];
789
790 size_t i = 0;
791 // Fill the C-arrays with the fields from all the events, as requested.
792 for (auto it = events.cbegin(); it != events.cend(); ++it) {
793 if (writeTOF)
794 tofs[i] = it->tof();
795 if (writePulsetime)
796 pulsetimes[i] = it->pulseTime().totalNanoseconds();
797 if (writeWeight)
798 weights[i] = it->weight();
799 if (writeError)
800 errorSquareds[i] = it->errorSquared();
801 ++i;
802 }
803
804 // Write out all the required arrays.
805 int dims_array[1] = {static_cast<int>(num)};
806 // In this mode, compressing makes things extremely slow! Not to be used for
807 // managed event workspaces.
808 bool compress = true; //(num > 100);
809 if (writeTOF)
810 NXwritedata("tof", NX_FLOAT64, 1, dims_array, tofs, compress);
811 if (writePulsetime)
812 NXwritedata("pulsetime", NX_INT64, 1, dims_array, pulsetimes, compress);
813 if (writeWeight)
814 NXwritedata("weight", NX_FLOAT32, 1, dims_array, weights, compress);
815 if (writeError)
816 NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, errorSquareds, compress);
817
818 // Free mem.
819 delete[] tofs;
820 delete[] weights;
821 delete[] errorSquareds;
822 delete[] pulsetimes;
823}
824
825//-------------------------------------------------------------------------------------
830int NexusFileIO::writeEventList(const DataObjects::EventList &el, const std::string &group_name) const {
831 // write data entry
832 NXstatus status = NXmakegroup(fileID, group_name.c_str(), "NXdata");
833 if (status == NX_ERROR)
834 return (2);
835 NXopengroup(fileID, group_name.c_str(), "NXdata");
836
837 // Copy the detector IDs to an array.
838 const auto &dets = el.getDetectorIDs();
839
840 // Write out the detector IDs
841 if (!dets.empty()) {
842 std::vector<detid_t> detectorIDs(dets.begin(), dets.end());
843 int dims_array[1];
844 NXwritedata("detector_IDs", NX_INT64, 1, dims_array, detectorIDs.data(), false);
845 }
846
847 std::string eventType("UNKNOWN");
848 size_t num = el.getNumberEvents();
849 switch (el.getEventType()) {
850 case TOF:
851 eventType = "TOF";
852 writeEventListData(el.getEvents(), true, true, false, false);
853 break;
854 case WEIGHTED:
855 eventType = "WEIGHTED";
856 writeEventListData(el.getWeightedEvents(), true, true, true, true);
857 break;
858 case WEIGHTED_NOTIME:
859 eventType = "WEIGHTED_NOTIME";
860 writeEventListData(el.getWeightedEventsNoTime(), true, false, true, true);
861 break;
862 }
863
864 // --- Save the type of sorting -----
865 std::string sortType;
866 switch (el.getSortType()) {
867 case TOF_SORT:
868 sortType = "TOF_SORT";
869 break;
870 case PULSETIME_SORT:
871 sortType = "PULSETIME_SORT";
872 break;
873 case UNSORTED:
874 default:
875 sortType = "UNSORTED";
876 break;
877 }
878 NXputattr(fileID, "sort_type", sortType.c_str(), static_cast<int>(sortType.size()), NX_CHAR);
879
880 // Save an attribute with the type of each event.
881 NXputattr(fileID, "event_type", eventType.c_str(), static_cast<int>(eventType.size()), NX_CHAR);
882 // Save an attribute with the number of events
883 NXputattr(fileID, "num_events", &num, 1, NX_INT64);
884
885 // Close it up!
886 status = NXclosegroup(fileID);
887 return ((status == NX_ERROR) ? 3 : 0);
888}
889
890//-------------------------------------------------------------------------------------
896int NexusFileIO::getWorkspaceSize(int &numberOfSpectra, int &numberOfChannels, int &numberOfXpoints,
897 bool &uniformBounds, std::string &axesUnits, std::string &yUnits) const {
898 NXstatus status;
899 // open workspace group
900 status = NXopengroup(fileID, "workspace", "NXdata");
901 if (status == NX_ERROR)
902 return (1);
903 // open "values" data which is identified by attribute "signal", if it exists
904 std::string entry;
905 if (checkEntryAtLevelByAttribute("signal", entry))
906 status = NXopendata(fileID, entry.c_str());
907 else {
908 NXclosegroup(fileID);
909 return (2);
910 }
911 if (status == NX_ERROR) {
912 NXclosegroup(fileID);
913 return (2);
914 }
915 // read workspace data size
916 int rank, dim[2], type;
917 status = NXgetinfo(fileID, &rank, dim, &type);
918 if (status == NX_ERROR)
919 return (3);
920 numberOfSpectra = dim[0];
921 numberOfChannels = dim[1];
922 // get axes attribute
923 char sbuf[NX_MAXNAMELEN];
924 int len = NX_MAXNAMELEN;
925 type = NX_CHAR;
926
927 char unitsAttrName[] = "units";
928 if (checkAttributeName(unitsAttrName)) {
929 status = NXgetattr(fileID, unitsAttrName, sbuf, &len, &type);
930 if (status != NX_ERROR)
931 yUnits = sbuf;
932 NXclosedata(fileID);
933 }
934 //
935 // read axis1 size
936 status = NXopendata(fileID, "axis1");
937 if (status == NX_ERROR)
938 return (4);
939 len = NX_MAXNAMELEN;
940 type = NX_CHAR;
941 NXgetattr(fileID, unitsAttrName, sbuf, &len, &type);
942 axesUnits = std::string(sbuf, len);
943 NXgetinfo(fileID, &rank, dim, &type);
944 // non-uniform X has 2D axis1 data
945 if (rank == 1) {
946 numberOfXpoints = dim[0];
947 uniformBounds = true;
948 } else {
949 numberOfXpoints = dim[1];
950 uniformBounds = false;
951 }
952 NXclosedata(fileID);
953 NXopendata(fileID, "axis2");
954 len = NX_MAXNAMELEN;
955 type = NX_CHAR;
956 NXgetattr(fileID, unitsAttrName, sbuf, &len, &type);
957 axesUnits += std::string(":") + std::string(sbuf, len);
958 NXclosedata(fileID);
959 NXclosegroup(fileID);
960 return (0);
961}
962
963bool NexusFileIO::checkAttributeName(const std::string &target) const {
964 // see if the given attribute name is in the current level
965 // return true if it is.
966 // clang-format off
967 const std::vector< ::NeXus::AttrInfo> infos = m_filehandle->getAttrInfos();
968 // clang-format on
969 return std::any_of(infos.cbegin(), infos.cend(), [&target](const auto &info) { return info.name == target; });
970}
971
972int NexusFileIO::getXValues(MantidVec &xValues, const int &spectra) const {
973 //
974 // find the X values for spectra. If uniform, the spectra number is ignored.
975 //
976 int rank, dim[2], type;
977
978 // open workspace group
979 NXstatus status = NXopengroup(fileID, "workspace", "NXdata");
980 if (status == NX_ERROR)
981 return (1);
982 // read axis1 size
983 status = NXopendata(fileID, "axis1");
984 if (status == NX_ERROR)
985 return (2);
986 NXgetinfo(fileID, &rank, dim, &type);
987 if (rank == 1) {
988 NXgetdata(fileID, xValues.data());
989 } else {
990 int start[2] = {spectra, 0};
991 int size[2] = {1, dim[1]};
992 NXgetslab(fileID, xValues.data(), start, size);
993 }
994 NXclosedata(fileID);
995 NXclosegroup(fileID);
996 return (0);
997}
998
999int NexusFileIO::getSpectra(MantidVec &values, MantidVec &errors, const int &spectra) const {
1000 //
1001 // read the values and errors for spectra
1002 //
1003 int rank, dim[2], type;
1004
1005 // open workspace group
1006 NXstatus status = NXopengroup(fileID, "workspace", "NXdata");
1007 if (status == NX_ERROR)
1008 return (1);
1009 std::string entry;
1010 if (checkEntryAtLevelByAttribute("signal", entry))
1011 status = NXopendata(fileID, entry.c_str());
1012 else {
1013 NXclosegroup(fileID);
1014 return (2);
1015 }
1016 if (status == NX_ERROR) {
1017 NXclosegroup(fileID);
1018 return (2);
1019 }
1020 NXgetinfo(fileID, &rank, dim, &type);
1021 // get buffer and block size
1022 int start[2] = {spectra - 1, 0};
1023 int size[2] = {1, dim[1]};
1024 NXgetslab(fileID, values.data(), start, size);
1025 NXclosedata(fileID);
1026
1027 // read errors
1028 status = NXopendata(fileID, "errors");
1029 if (status == NX_ERROR)
1030 return (2);
1031 NXgetinfo(fileID, &rank, dim, &type);
1032 // set block size;
1033 size[1] = dim[1];
1034 NXgetslab(fileID, errors.data(), start, size);
1035 NXclosedata(fileID);
1036
1037 NXclosegroup(fileID);
1038
1039 return (0);
1040}
1041
1043 // search exiting file for entries of form mantid_workspace_<n> and return
1044 // count
1045 int count = 0;
1046 std::map<std::string, std::string> entries = m_filehandle->getEntries();
1047 for (auto &entrie : entries) {
1048 if (entrie.second == "NXentry") {
1049 if (entrie.first.find("mantid_workspace_") == 0)
1050 count++;
1051 }
1052 }
1053
1054 return count;
1055}
1056
1057bool NexusFileIO::checkEntryAtLevel(const std::string &item) const {
1058 // Search the currently open level for name "item"
1059 std::map<std::string, std::string> entries = m_filehandle->getEntries();
1060 return std::any_of(entries.cbegin(), entries.cend(), [&item](const auto &entry) { return entry.first == item; });
1061}
1062
1063bool NexusFileIO::checkEntryAtLevelByAttribute(const std::string &attribute, std::string &entry) const {
1064 // Search the currently open level for a section with "attribute" and return
1065 // entry name
1066 std::map<std::string, std::string> entries = m_filehandle->getEntries();
1067 for (auto &entrie : entries) {
1068 if (entrie.second == "SDS") {
1069 m_filehandle->openData(entrie.first);
1070 bool result = checkAttributeName(attribute);
1071 m_filehandle->closeData();
1072 if (result) {
1073 entry = entrie.first;
1074 return true;
1075 }
1076 }
1077 }
1078
1079 return (false);
1080}
1081
1088 std::vector<int> spectra;
1089 std::vector<std::size_t> bins;
1090 std::vector<double> weights;
1091 int spectra_count = 0;
1092 int offset = 0;
1093 for (std::size_t i = 0; i < ws->getNumberHistograms(); ++i) {
1094 if (ws->hasMaskedBins(i)) {
1095 const API::MatrixWorkspace::MaskList &mList = ws->maskedBins(i);
1096 spectra.emplace_back(spectra_count);
1097 spectra.emplace_back(offset);
1098 for (const auto &mask : mList) {
1099 bins.emplace_back(mask.first);
1100 weights.emplace_back(mask.second);
1101 }
1102 ++spectra_count;
1103 offset += static_cast<int>(mList.size());
1104 }
1105 }
1106
1107 if (spectra_count == 0)
1108 return false;
1109
1110 NXstatus status;
1111
1112 // save spectra offsets as a 2d array of ints
1113 int dimensions[2]{spectra_count, 2};
1114 status = NXmakedata(fileID, "masked_spectra", NX_INT32, 2, dimensions);
1115 if (status == NX_ERROR)
1116 return false;
1117 NXopendata(fileID, "masked_spectra");
1118 const std::string description = "spectra index,offset in masked_bins and mask_weights";
1119 NXputattr(fileID, "description", description.c_str(), static_cast<int>(description.size() + 1), NX_CHAR);
1120 NXputdata(fileID, spectra.data());
1121 NXclosedata(fileID);
1122
1123 // save masked bin indices
1124 dimensions[0] = static_cast<int>(bins.size());
1125 status = NXmakedata(fileID, "masked_bins", NX_UINT64, 1, dimensions);
1126 if (status == NX_ERROR)
1127 return false;
1128 NXopendata(fileID, "masked_bins");
1129 NXputdata(fileID, bins.data());
1130 NXclosedata(fileID);
1131
1132 // save masked bin weights
1133 dimensions[0] = static_cast<int>(bins.size());
1134 status = NXmakedata(fileID, "mask_weights", NX_FLOAT64, 1, dimensions);
1135 if (status == NX_ERROR)
1136 return false;
1137 NXopendata(fileID, "mask_weights");
1138 NXputdata(fileID, weights.data());
1139 NXclosedata(fileID);
1140
1141 return true;
1142}
1143
1144template <> std::string NexusFileIO::logValueType<double>() const { return "double"; }
1145
1146template <> std::string NexusFileIO::logValueType<int>() const { return "int"; }
1147
1148template <> std::string NexusFileIO::logValueType<bool>() const { return "bool"; }
1149
1163int getNexusEntryTypes(const std::string &fileName, std::vector<std::string> &entryName,
1164 std::vector<std::string> &definition) {
1165 //
1166 //
1167 NXhandle fileH;
1168 NXaccess mode = NXACC_READ;
1169 NXstatus stat = NXopen(fileName.c_str(), mode, &fileH);
1170 if (stat == NX_ERROR)
1171 return (-1);
1172 //
1173 entryName.clear();
1174 definition.clear();
1175 char *nxname, *nxclass;
1176 int nxdatatype;
1177 nxname = new char[NX_MAXNAMELEN];
1178 nxclass = new char[NX_MAXNAMELEN];
1179 int rank, dims[2], type;
1180 //
1181 // Loop through all entries looking for the definition section in each (or
1182 // analysis for MuonV1)
1183 //
1184 std::vector<std::string> entryList;
1185 while ((stat = NXgetnextentry(fileH, nxname, nxclass, &nxdatatype)) == NX_OK) {
1186 std::string nxc(nxclass);
1187 if (nxc == "NXentry")
1188 entryList.emplace_back(nxname);
1189 }
1190 // for each entry found, look for "analysis" or "definition" text data fields
1191 // and return value plus entry name
1192 for (auto &entry : entryList) {
1193 NXopengroup(fileH, entry.c_str(), "NXentry");
1194 // loop through field names in this entry
1195 while ((NXgetnextentry(fileH, nxname, nxclass, &nxdatatype)) == NX_OK) {
1196 std::string nxc(nxclass), nxn(nxname);
1197 // if a data field
1198 if (nxc == "SDS")
1199 // if one of the two names we are looking for
1200 if (nxn == "definition" || nxn == "analysis") {
1201 NXopendata(fileH, nxname);
1202 stat = NXgetinfo(fileH, &rank, dims, &type);
1203 if (stat == NX_ERROR)
1204 continue;
1205 auto value = new char[dims[0] + 1];
1206 stat = NXgetdata(fileH, value);
1207 if (stat == NX_ERROR)
1208 continue;
1209 value[dims[0]] = '\0';
1210 // return e.g entryName "analysis"/definition "muonTD"
1211 definition.emplace_back(value);
1212 entryName.emplace_back(entry);
1213 delete[] value;
1214 NXclosegroup(fileH); // close data group, then entry
1215 NXclosegroup(fileH);
1216 break;
1217 }
1218 }
1219 }
1220 NXclose(&fileH);
1221 delete[] nxname;
1222 delete[] nxclass;
1223 return (static_cast<int>(entryName.size()));
1224}
1225
1230 // Close the nexus file if not already closed.
1231 // this->closeNexusFile();
1232}
1233
1234} // namespace Mantid::NeXus
const std::vector< double > & rhs
double value
The value of the point.
Definition: FitMW.cpp:51
int count
counter
Definition: Matrix.cpp:37
Class to represent the axis of a workspace.
Definition: Axis.h:30
virtual std::string label(const std::size_t &index) const =0
Returns a text label of for a value Note that the index here is not the index of a value,...
virtual bool isText() const
Returns true if the axis is Text.
Definition: Axis.h:54
virtual std::size_t length() const =0
Get the length of the axis.
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
Definition: Axis.cpp:28
virtual bool isSpectra() const
Returns true is the axis is a Spectra axis.
Definition: Axis.h:50
Column is the base class for columns of TableWorkspace.
Definition: Column.h:35
T & cell(size_t index)
Templated method for returning a value. No type checks are done.
Definition: Column.h:127
virtual size_t size() const =0
Number of individual elements in the column.
ConstColumnVector gives const access to the column elements without alowing its resizing.
size_t size()
Size of the vector.
const std::set< detid_t > & getDetectorIDs() const
Get a const reference to the detector IDs set.
Definition: ISpectrum.cpp:113
std::map< size_t, double > MaskList
Masked bins for each spectrum are stored as a set of pairs containing <bin index, weight>
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A class for holding :
Definition: EventList.h:56
std::vector< Types::Event::TofEvent > & getEvents()
Return the list of TofEvents contained.
Definition: EventList.cpp:780
EventSortType getSortType() const
Return the type of sorting used in this event list.
Definition: EventList.cpp:1104
std::size_t getNumberEvents() const override
Return the number of events in the list.
Definition: EventList.cpp:1143
Mantid::API::EventType getEventType() const override
Return the type of Event vector contained within.
Definition: EventList.cpp:643
std::vector< WeightedEventNoTime > & getWeightedEventsNoTime()
Return the list of WeightedEvent contained.
Definition: EventList.cpp:823
std::vector< WeightedEvent > & getWeightedEvents()
Return the list of WeightedEvent contained.
Definition: EventList.cpp:795
Records the filename and the description of failure.
Definition: Exception.h:98
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void reportIncrement(int inc, const std::string &msg="")
Sends the progress notification and increment the loop counter by more than one.
Class for 3D vectors.
Definition: V3D.h:34
API::Progress * m_progress
Allow an externally supplied progress object to be used.
Definition: NexusFileIO.h:109
boost::optional< size_t > optional_size_t
Definition: NexusFileIO.h:42
int writeNexusProcessedDataEventCombined(const DataObjects::EventWorkspace_const_sptr &ws, std::vector< int64_t > &indices, double *tofs, float *weights, float *errorSquareds, int64_t *pulsetimes, bool compress) const
Write out a combined chunk of event data.
void writeNexusVectorColumn(const API::Column_const_sptr &col, const std::string &columnName, int nexusType, const std::string &interpret_as) const
Writes given vector column to the currently open Nexus file.
std::string m_filename
nexus file name
Definition: NexusFileIO.h:164
int writeNexusProcessedHeader(const std::string &title, const std::string &wsName="") const
write the header ifon for the Mantid workspace format
bool checkEntryAtLevelByAttribute(const std::string &attribute, std::string &entry) const
Look for entry with given attribute (eg "signal")
std::shared_ptr< ::NeXus::File > m_filehandle
C++ API file handle.
Definition: NexusFileIO.h:104
int writeNexusTableWorkspace(const API::ITableWorkspace_const_sptr &itableworkspace, const char *group_name) const
write table workspace
bool checkAttributeName(const std::string &target) const
check if given attribute name is in currently opened entry
bool writeNexusBinMasking(const API::MatrixWorkspace_const_sptr &ws) const
write bin masking information
int getXValues(MantidVec &xValues, const int &spectra) const
read X values for one (or the generic if uniform) spectra
NexusFileIO()
Default constructor.
Definition: NexusFileIO.cpp:45
int writeNexusProcessedData2D(const API::MatrixWorkspace_const_sptr &localworkspace, const bool &uniformSpectra, const std::vector< int > &indices, const char *group_name, bool write2Ddata) const
write the workspace data
bool checkEntryAtLevel(const std::string &item) const
check if the gievn item exists in the current level
int findMantidWSEntries() const
search for exisiting MantidWorkpace_n entries in opened file
void writeNxFloatArray(const std::string &name, const std::vector< double > &values, const std::vector< std::string > &attributes, const std::vector< std::string > &avalues) const
write a float array along with any defined attributes
int writeNexusProcessedDataEvent(const DataObjects::EventWorkspace_const_sptr &ws)
Write out all of the event lists in the given workspace.
bool writeNxStringArray(const std::string &name, const std::vector< std::string > &values, const std::vector< std::string > &attributes, const std::vector< std::string > &avalues) const
write a char array along with any defined attributes
void resetProgress(Mantid::API::Progress *prog)
Reset the pointer to the progress object.
Definition: NexusFileIO.cpp:52
void openNexusWrite(const std::string &fileName, optional_size_t entryNumber=optional_size_t(), const bool append_to_file=true)
open the nexus file for writing
Definition: NexusFileIO.cpp:80
int getWorkspaceSize(int &numberOfSpectra, int &numberOfChannels, int &numberOfXpoints, bool &uniformBounds, std::string &axesUnits, std::string &yUnits) const
find size of open entry data section
int writeEventList(const DataObjects::EventList &el, const std::string &group_name) const
Write out an event list into an already-opened group.
int m_nexuscompression
Nexus compression method.
Definition: NexusFileIO.h:107
void closeNexusFile()
close the nexus file
void NXwritedata(const char *name, int datatype, int rank, int *dims_array, void *data, bool compress=false) const
Write out an array to the open file.
void writeEventListData(std::vector< T > events, bool writeTOF, bool writePulsetime, bool writeWeight, bool writeError) const
Write out the event list data, no matter what the underlying event type is.
void writeTableColumn(int type, const std::string &interpret_as, const API::Column &col, const std::string &columnName) const
Save a numeric columns of a TableWorkspace to currently open nexus file.
NXhandle fileID
Nexus file handle.
Definition: NexusFileIO.h:99
void closeGroup()
Close the group.
int getSpectra(MantidVec &values, MantidVec &errors, const int &spectra) const
read values and errors for spectra
bool writeNxNote(const std::string &noteName, const std::string &author, const std::string &date, const std::string &description, const std::string &pairValues) const
write an NXnote with standard fields (but NX_CHAR rather than NX_BINARY data)
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< const ITableWorkspace > ITableWorkspace_const_sptr
shared pointer to Mantid::API::ITableWorkspace (const version)
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< const Column > Column_const_sptr
Definition: Column.h:229
@ WEIGHTED_NOTIME
Definition: IEventList.h:18
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< const RebinnedOutput > RebinnedOutput_const_sptr
shared pointer to a const RebinnedOutput
MANTID_NEXUS_DLL int getNexusEntryTypes(const std::string &fileName, std::vector< std::string > &entryName, std::vector< std::string > &definition)
Get all the Nexus entry types for a file.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition: cow_ptr.h:172
std::string to_string(const wide_integer< Bits, Signed > &n)
As TableColumn stores its data in a std::vector bool type cannot be used in the same way as the other...
Definition: Column.h:209