Mantid
Loading...
Searching...
No Matches
LoadMcStas.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 +
21#include "MantidKernel/Unit.h"
23#include "MantidNexus/H5Util.h"
24
25#include <H5Cpp.h>
26#include <boost/algorithm/string.hpp>
27
28namespace Mantid::DataHandling {
29using namespace Kernel;
30using namespace API;
31using namespace DataObjects;
32using namespace Nexus;
33
34// Register the algorithm into the AlgorithmFactory
36
37//----------------------------------------------------------------------------------------------
38// Algorithm's name for identification. @see Algorithm::name
39const std::string LoadMcStas::name() const { return "LoadMcStas"; }
40
41// Algorithm's version for identification. @see Algorithm::version
42int LoadMcStas::version() const { return 1; }
43
44// Algorithm's category for identification. @see Algorithm::category
45const std::string LoadMcStas::category() const { return "DataHandling\\Nexus"; }
46
47//----------------------------------------------------------------------------------------------
48
49//----------------------------------------------------------------------------------------------
53 const std::vector<std::string> exts{".h5", ".nxs"};
54 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, exts),
55 "The name of the Nexus file to load");
56
57 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputWorkspace", "", Direction::Output),
58 "An output workspace.");
59
60 declareProperty("ErrorBarsSetTo1", false,
61 "When this property is set to false errors are set equal to data values, "
62 "and when set to true all errors are set equal to one. This property "
63 "defaults to false");
64
65 declareProperty("OutputOnlySummedEventWorkspace", true,
66 "When true the algorithm only outputs the sum of all event data into "
67 "one eventworkspace EventData + _ + name of the OutputWorkspace. "
68 "If false eventworkspaces are also returned for each individual "
69 "McStas components storing event data");
70}
71
72//----------------------------------------------------------------------------------------------
76 std::string filename = getPropertyValue("Filename");
77 H5::H5File file(filename, H5F_ACC_RDONLY, Nexus::H5Util::defaultFileAcc());
78
79 auto const &descriptor = getFileInfo();
80 auto const &allEntries = descriptor->getAllEntries();
81
82 auto const iterSDS = allEntries.find("SDS");
83 if (iterSDS == allEntries.cend()) {
84 throw std::runtime_error("Could not find any entries.");
85 }
86 auto const &entries = iterSDS->second;
87
88 const char *attributeName = "long_name";
89 std::vector<std::string> eventEntries;
90 std::map<std::string, std::vector<std::string>> histogramEntries;
91 for (auto &entry : entries) {
92 if (entry.find("/entry1/data") == std::string::npos) {
93 continue;
94 }
95
96 const auto parts = Strings::StrParts(entry, boost::regex("/"));
97 const auto groupAddress = "/" + Strings::join(parts.cbegin(), parts.cend() - 1, "/");
98 const auto groupName = *(parts.cend() - 2);
99 const auto datasetName = parts.back();
100
101 if (groupName == "content_nxs")
102 continue;
103
104 const H5::Group group = file.openGroup(groupAddress);
105 const H5::DataSet dataset = group.openDataSet(datasetName);
106
107 if (!H5Util::hasAttribute(dataset, attributeName)) {
108 continue;
109 }
110
111 std::string nameAttrValue;
112 H5Util::readStringAttribute(dataset, attributeName, nameAttrValue);
113 if (nameAttrValue.find("Neutron_ID") != std::string::npos) {
114 eventEntries.emplace_back(groupAddress);
115 } else if (histogramEntries.find(groupAddress) == histogramEntries.cend()) {
116 histogramEntries[groupAddress] = {datasetName};
117 } else {
118 histogramEntries[groupAddress].emplace_back(datasetName);
119 }
120 }
121
122 std::vector<std::string> scatteringWSNames;
123 if (!eventEntries.empty()) {
124 scatteringWSNames = readEventData(eventEntries, file);
125 }
126 const auto histoWSNames = readHistogramData(histogramEntries, file);
127 file.close();
128
129 // join two vectors together
130 scatteringWSNames.insert(scatteringWSNames.end(), histoWSNames.cbegin(), histoWSNames.cend());
131
132 setProperty("OutputWorkspace", groupWorkspaces(scatteringWSNames));
133}
134
140API::WorkspaceGroup_sptr LoadMcStas::groupWorkspaces(const std::vector<std::string> &workspaces) const {
141 auto groupAlgorithm = API::AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces");
142 groupAlgorithm->setChild(true);
143 groupAlgorithm->setLogging(false);
144 groupAlgorithm->initialize();
145 groupAlgorithm->setProperty("InputWorkspaces", workspaces);
146 groupAlgorithm->setProperty("OutputWorkspace", "__grouped");
147 groupAlgorithm->execute();
148 return groupAlgorithm->getProperty("OutputWorkspace");
149}
150
157std::vector<std::string> LoadMcStas::readEventData(const std::vector<std::string> &eventEntries,
158 const H5::H5File &file) {
159
160 // vector to store output workspaces
161 std::vector<std::string> scatteringWSNames;
162
163 std::string filename = getPropertyValue("Filename");
164 const bool errorBarsSetTo1 = getProperty("ErrorBarsSetTo1");
165
166 Geometry::Instrument_sptr instrument;
167
168 // Initialize progress reporting
169 int reports = 2;
170 const double progressFractionInitial = 0.1;
171 Progress progInitial(this, 0.0, progressFractionInitial, reports);
172
173 std::string instrumentXML;
174 progInitial.report("Loading instrument");
175 try {
176 const H5::Group group = file.openGroup("/entry1/instrument/instrument_xml");
177 const H5::DataSet dataset = group.openDataSet("data");
178 instrumentXML = H5Util::readString(dataset);
179 } catch (...) {
180 g_log.warning() << "\nCould not find the instrument description in the Nexus file:" << filename
181 << " Ignore eventdata from the Nexus file\n";
182 return scatteringWSNames;
183 ;
184 }
185
186 try {
187 std::string instrumentName = "McStas";
188 Geometry::InstrumentDefinitionParser parser(filename, instrumentName, instrumentXML);
189 std::string instrumentNameMangled = parser.getMangledName();
190
191 // Check whether the instrument is already in the InstrumentDataService
192 if (InstrumentDataService::Instance().doesExist(instrumentNameMangled)) {
193 // If it does, just use the one from the one stored there
194 instrument = InstrumentDataService::Instance().retrieve(instrumentNameMangled);
195 } else {
196 // Really create the instrument
197 instrument = parser.parseXML(nullptr);
198 // Add to data service for later retrieval
199 InstrumentDataService::Instance().add(instrumentNameMangled, instrument);
200 }
202 g_log.warning() << "When trying to read the instrument description in the Nexus file: " << filename
203 << " the following error is reported: " << e.what() << " Ignore eventdata from the Nexus file\n";
204 return scatteringWSNames;
205 ;
206 } catch (...) {
207 g_log.warning() << "Could not parse instrument description in the Nexus file: " << filename
208 << " Ignore eventdata from the Nexus file\n";
209 return scatteringWSNames;
210 ;
211 }
212
213 // create and prepare an event workspace ready to receive the mcstas events
214 progInitial.report("Set up EventWorkspace");
215 EventWorkspace_sptr eventWS(new EventWorkspace());
216 // initialize, where create up front number of eventlists = number of
217 // detectors
218 eventWS->initialize(instrument->getNumberDetectors(), 1, 1);
219 // Set the units
220 eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
221 eventWS->setYUnit("Counts");
222 // set the instrument
223 eventWS->setInstrument(instrument);
224 // assign detector ID to eventlists
225
226 std::vector<detid_t> detIDs = instrument->getDetectorIDs();
227
228 for (size_t i = 0; i < instrument->getNumberDetectors(); i++) {
229 eventWS->getSpectrum(i).addDetectorID(detIDs[i]);
230 // spectrum number are treated as equal to detector IDs for McStas data
231 eventWS->getSpectrum(i).setSpectrumNo(detIDs[i]);
232 }
233 // the one is here for the moment for backward compatibility
234 eventWS->rebuildSpectraMapping(true);
235 const auto detIDtoWSIndex = eventWS->getDetectorIDToWorkspaceIndexMap(true);
236
237 bool isAnyNeutrons = false;
238 // to store shortest and longest recorded TOF
239 double shortestTOF(0.0);
240 double longestTOF(0.0);
241
242 // create vector container all the event output workspaces needed
243 const size_t numEventEntries = eventEntries.size();
244 std::string nameOfGroupWS = getProperty("OutputWorkspace");
245 const auto eventDataTotalName = "EventData_" + nameOfGroupWS;
246 std::vector<std::pair<EventWorkspace_sptr, std::string>> allEventWS = {{eventWS, eventDataTotalName}};
247 // if numEventEntries > 1 also create separate event workspaces
248 const bool onlySummedEventWorkspace = getProperty("OutputOnlySummedEventWorkspace");
249 if (!onlySummedEventWorkspace && numEventEntries > 1) {
250 for (const auto &eventEntry : eventEntries) {
251 const auto parts = Strings::StrParts(eventEntry, boost::regex("/"));
252 const auto groupName = parts.back();
253 // create container to hold partial event data
254 // plus the name users will see for it
255 const auto ws_name = groupName + "_" + nameOfGroupWS;
256 allEventWS.emplace_back(eventWS->clone(), ws_name);
257 }
258 }
259
260 Progress progEntries(this, progressFractionInitial, 1.0, numEventEntries * 2);
261
262 // Refer to entry in allEventWS. The first non-summed workspace index is 1
263 auto eventWSIndex = 1u;
264 // Loop over McStas event data components
265 for (const auto &groupAddress : eventEntries) {
266 const H5::Group group = file.openGroup(groupAddress);
267 const H5::DataSet dataset = group.openDataSet("events");
268
269 // open second level entry
270 std::vector<double> data;
271 progEntries.report("read event data from nexus");
272
273 // Need to take into account that the nexus readData method reads a
274 // multi-column data entry
275 // into a vector
276 // The number of data column for each neutron is here hardcoded to (p, x,
277 // y, n, id, t)
278 // Thus we have
279 // column 0 : p neutron wight
280 // column 1 : x x coordinate
281 // column 2 : y y coordinate
282 // column 3 : n accumulated number of neutrons
283 // column 4 : id pixel id
284 // column 5 : t time
285
286 // get info about event data
287 const H5::DataSpace dataspace = dataset.getSpace();
288 const auto rank = dataspace.getSimpleExtentNdims();
289
290 std::vector<hsize_t> dims(rank);
291 dataspace.getSimpleExtentDims(dims.data());
292 if (dims.size() != 2) {
293 g_log.error() << "Event data in McStas nexus file not loaded. Expected "
294 "event data block to be two dimensional\n";
295 return scatteringWSNames;
296 }
297 hsize_t nNeutrons = dims[0];
298 hsize_t numberOfDataColumn = dims[1];
299 if (nNeutrons && numberOfDataColumn != 6) {
300 g_log.error() << "Event data in McStas nexus file expecting 6 columns\n";
301 return scatteringWSNames;
302 ;
303 }
304 if (!isAnyNeutrons && nNeutrons > 0)
305 isAnyNeutrons = true;
306
307 hsize_t start[2];
308 hsize_t step[2];
309
310 // read the event data in blocks. 1 million event is 1000000*6*8 doubles
311 // about 50Mb
312 hsize_t nNeutronsInBlock = 1000000;
313 hsize_t nOfFullBlocks = nNeutrons / nNeutronsInBlock;
314 hsize_t nRemainingNeutrons = nNeutrons - nOfFullBlocks * nNeutronsInBlock;
315 // sum over number of blocks + 1 to cover the remainder
316 for (hsize_t iBlock = 0; iBlock < nOfFullBlocks + 1; iBlock++) {
317 if (iBlock == nOfFullBlocks) {
318 // read remaining neutrons
319 start[0] = nOfFullBlocks * nNeutronsInBlock;
320 start[1] = 0;
321 step[0] = nRemainingNeutrons;
322 step[1] = numberOfDataColumn;
323 } else {
324 // read neutrons in a full block
325 start[0] = iBlock * nNeutronsInBlock;
326 start[1] = 0;
327 step[0] = nNeutronsInBlock;
328 step[1] = numberOfDataColumn;
329 }
330 const hsize_t nNeutronsForthisBlock = step[0]; // number of neutrons read for this block
331 data.resize(nNeutronsForthisBlock * numberOfDataColumn);
332
333 // Check that the type is what it is supposed to be
334 const H5::DataType datatype = dataset.getDataType();
335 if (datatype.getClass() != H5T_FLOAT) {
336 g_log.warning() << "Entry event field is not H5T_FLOAT! It will be skipped.\n";
337 continue;
338 }
339
340 H5::DataSpace memspace(rank, step);
341 dataspace.selectHyperslab(H5S_SELECT_SET, step, start);
342
343 dataset.read(data.data(), H5::PredType::NATIVE_DOUBLE, memspace, dataspace);
344
345 // populate workspace with McStas events
346 progEntries.report("read event data into workspace");
347 for (hsize_t in = 0; in < nNeutronsForthisBlock; in++) {
348 const auto detectorID = static_cast<int>(data[4 + numberOfDataColumn * in]);
349 const double detector_time = data[5 + numberOfDataColumn * in] * 1.0e6; // convert to microseconds
350 if (in == 0 && iBlock == 0) {
351 shortestTOF = detector_time;
352 longestTOF = detector_time;
353 } else {
354 if (detector_time < shortestTOF)
355 shortestTOF = detector_time;
356 if (detector_time > longestTOF)
357 longestTOF = detector_time;
358 }
359
360 const size_t workspaceIndex = detIDtoWSIndex.find(detectorID)->second;
361
362 int64_t pulse_time = 0;
363 WeightedEvent weightedEvent;
364 if (errorBarsSetTo1) {
365 weightedEvent = WeightedEvent(detector_time, pulse_time, data[numberOfDataColumn * in], 1.0);
366 } else {
367 weightedEvent = WeightedEvent(detector_time, pulse_time, data[numberOfDataColumn * in],
368 data[numberOfDataColumn * in] * data[numberOfDataColumn * in]);
369 }
370 allEventWS[0].first->getSpectrum(workspaceIndex) += weightedEvent;
371 if (!onlySummedEventWorkspace && numEventEntries > 1) {
372 allEventWS[eventWSIndex].first->getSpectrum(workspaceIndex) += weightedEvent;
373 }
374 }
375 eventWSIndex++;
376 } // end reading over number of blocks of an event dataset
377 } // end reading over number of event datasets
378
379 // Create a default TOF-vector for histogramming, for now just 2 bins
380 // 2 bins is the standard. However for McStas simulation data it may make
381 // sense to
382 // increase this number for better initial visual effect
383
384 auto axis = HistogramData::BinEdges{shortestTOF - 1, longestTOF + 1};
385
386 // ensure that specified name is given to workspace (eventWS) when added to
387 // outputGroup
388 for (const auto &wsAndName : allEventWS) {
389 const auto ws = wsAndName.first;
390 ws->setAllX(axis);
391 AnalysisDataService::Instance().addOrReplace(wsAndName.second, ws);
392 scatteringWSNames.emplace_back(wsAndName.second);
393 }
394 return scatteringWSNames;
395}
396
403std::vector<std::string>
404LoadMcStas::readHistogramData(const std::map<std::string, std::vector<std::string>> &histogramEntries,
405 const H5::H5File &file) {
406
407 std::string nameAttrValueYLABEL;
408 std::vector<std::string> histoWSNames;
409
410 for (const auto &entry : histogramEntries) {
411 const auto groupAddress = entry.first;
412 const H5::Group group = file.openGroup(groupAddress);
413
414 std::string nameAttrValueTITLE;
415 H5Util::readStringAttribute(group, "filename", nameAttrValueTITLE);
416
417 if (H5Util::hasAttribute(group, "ylabel")) {
418 H5Util::readStringAttribute(group, "ylabel", nameAttrValueYLABEL);
419 }
420
421 // Find the axis names
422 std::string axis1Name, axis2Name;
423 for (const auto &datasetName : entry.second) {
424 if (datasetName == "ncount")
425 continue;
426 H5::DataSet dataset = group.openDataSet(datasetName);
427
428 if (H5Util::hasAttribute(dataset, "axis")) {
429 const auto axisNo = H5Util::readNumAttributeCoerce<int>(dataset, "axis");
430 if (axisNo == 1)
431 axis1Name = datasetName;
432 else if (axisNo == 2)
433 axis2Name = datasetName;
434 else
435 throw std::invalid_argument("Unknown axis number");
436 }
437 }
438
439 std::vector<double> axis1Values;
440 H5Util::readArray1DCoerce(group, axis1Name, axis1Values);
441 std::vector<double> axis2Values;
442
443 if (axis2Name.length() == 0) {
444 axis2Name = nameAttrValueYLABEL;
445 axis2Values.emplace_back(0.0);
446 } else {
447 H5Util::readArray1DCoerce(group, axis2Name, axis2Values);
448 }
449
450 const size_t axis1Length = axis1Values.size();
451 const size_t axis2Length = axis2Values.size();
452 g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length << '\n';
453
454 // Require "data" field
455 std::vector<double> data;
456 H5Util::readArray1DCoerce(group, "data", data);
457
458 // Optional errors field
459 std::vector<double> errors;
460 if (group.exists("errors")) {
461 H5Util::readArray1DCoerce(group, "errors", errors);
462 }
463
464 MatrixWorkspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D", axis2Length, axis1Length, axis1Length);
465 Axis *axis1 = ws->getAxis(0);
466 axis1->title() = axis1Name;
467 // Set caption
468 auto lblUnit = std::make_shared<Units::Label>();
469 lblUnit->setLabel(axis1Name, "");
470 axis1->unit() = lblUnit;
471
472 auto axis2 = std::make_unique<NumericAxis>(axis2Length);
473 auto axis2Raw = axis2.get();
474 axis2->title() = axis2Name;
475 // Set caption
476 lblUnit = std::make_shared<Units::Label>();
477 lblUnit->setLabel(axis2Name, "");
478 axis2->unit() = lblUnit;
479
480 ws->setYUnit(axis2Name);
481 ws->replaceAxis(1, std::move(axis2));
482
483 for (size_t wsIndex = 0; wsIndex < axis2Length; ++wsIndex) {
484 auto &dataX = ws->mutableX(wsIndex);
485 auto &dataY = ws->mutableY(wsIndex);
486 auto &dataE = ws->mutableE(wsIndex);
487
488 for (size_t j = 0; j < axis1Length; ++j) {
489 // Data is stored in column-major order so we are translating to
490 // row major for Mantid
491 const size_t fileDataIndex = j * axis2Length + wsIndex;
492
493 dataX[j] = axis1Values[j];
494 dataY[j] = data[fileDataIndex];
495 if (!errors.empty())
496 dataE[j] = errors[fileDataIndex];
497 }
498 axis2Raw->setValue(wsIndex, axis2Values[wsIndex]);
499 }
500
501 // set the workspace title
502 ws->setTitle(nameAttrValueTITLE);
503
504 // use the workspace title to create the workspace name
505 std::replace(nameAttrValueTITLE.begin(), nameAttrValueTITLE.end(), ' ', '_');
506
507 // ensure that specified name is given to workspace (eventWS) when added to
508 // outputGroup
509 const std::string outputWS = getProperty("OutputWorkspace");
510 const std::string nameUserSee = nameAttrValueTITLE + "_" + outputWS;
511 AnalysisDataService::Instance().addOrReplace(nameUserSee, ws);
512
513 histoWSNames.emplace_back(ws->getName());
514 }
515 return histoWSNames;
516}
517
525 if (!descriptor.isEntry("/entry1/simulation/name")) {
526 return 0;
527 }
528 H5::H5File file(descriptor.filename(), H5F_ACC_RDONLY, Nexus::H5Util::defaultFileAcc());
529 H5::Group group = file.openGroup("/entry1/simulation");
530 H5::DataSet dataset = group.openDataSet("name");
531
532 const auto value = H5Util::readString(dataset);
533 if (boost::iequals(value, "mccode")) {
534 return 98;
535 }
536 return 0;
537}
538
539} // namespace Mantid::DataHandling
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
uint64_t hsize_t
#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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
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
virtual const std::shared_ptr< Mantid::Nexus::NexusDescriptor > getFileInfo() const noexcept
Required to pass m_fileInfo to static functions Keeping it shared_ptr to match setFileInfo signature ...
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
void init() override
Initialize the algorithm's properties.
std::vector< std::string > readHistogramData(const std::map< std::string, std::vector< std::string > > &histogramEntries, const H5::H5File &file)
Read histogram data.
API::WorkspaceGroup_sptr groupWorkspaces(const std::vector< std::string > &workspaces) const
Group workspaces.
void execLoader() override
Execute the algorithm.
std::vector< std::string > readEventData(const std::vector< std::string > &eventEntries, const H5::H5File &file)
Read Event Data.
int confidence(Nexus::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
const std::string category() const override
function to return a category of the algorithm.
int version() const override
function to return a version of the algorithm, must be overridden in all algorithms
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
Info about a single neutron detection event, including a weight and error value:
Definition Events.h:39
Creates an instrument data from a XML instrument description file.
std::shared_ptr< Instrument > parseXML(Kernel::ProgressBase *progressReporter)
Parse XML contents.
std::string getMangledName()
Handle used in the singleton constructor for instrument file should append the value file sha-1 check...
Exception for errors associated with the instrument definition.
Definition Exception.h:220
const char * what() const noexcept override
Writes out the range and limits.
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 error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
bool isEntry(const std::string &entryName, const std::string &groupClass) const noexcept
Checks if a full-address entry exists for a particular groupClass in a Nexus dataset.
const std::string & filename() const noexcept
Returns a copy of the current file name.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, typename std::enable_if<!(std::is_same< typename std::iterator_traits< ITERATOR_TYPE >::iterator_category, std::random_access_iterator_tag >::value)>::type *=nullptr)
Join a set or vector of (something that turns into a string) together into one string,...
Definition Strings.h:84
MANTID_KERNEL_DLL std::vector< std::string > StrParts(std::string, const boost::regex &)
Split a line into component parts.
MANTID_NEXUS_DLL void readStringAttribute(const H5::H5Object &object, const std::string &attributeName, std::string &output)
Definition H5Util.cpp:342
MANTID_NEXUS_DLL std::string readString(H5::H5File &file, const std::string &address)
Definition H5Util.cpp:266
MANTID_NEXUS_DLL bool hasAttribute(const H5::H5Object &object, const char *attributeName)
Definition H5Util.cpp:337
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
Definition H5Util.cpp:119
void readArray1DCoerce(const H5::Group &group, const std::string &name, std::vector< NumT > &output)
STL namespace.
@ Output
An output workspace.
Definition Property.h:54