Mantid
Loading...
Searching...
No Matches
LoadNXcanSAS.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 +
8
11#include "MantidAPI/Axis.h"
16#include "MantidAPI/Run.h"
17#include "MantidAPI/Workspace.h"
21#include "MantidKernel/Logger.h"
22#include "MantidNexus/H5Util.h"
23#include "MantidNexus/NexusFile.h"
24#include <H5Cpp.h>
25
26using namespace Mantid::Kernel;
27using namespace Mantid::API;
28using namespace Mantid::DataHandling::NXcanSAS;
29using namespace Mantid::Nexus;
30
31namespace {
32Mantid::Kernel::Logger g_log("LoadNXcanSAS");
33const std::string NX_SPIN_LOG = "spin_state_NXcanSAS";
34const std::map<std::string, int> SAMPLE_GEOMETRIES = {
35 {"cylinder", 1}, {"flat plate", 2}, {"flatplate", 2}, {"disc", 3}};
36
37std::string getNameOfEntry(const H5::H5File &root) {
38 auto numberOfObjects = root.getNumObjs();
39 if (numberOfObjects != 1) {
40 throw std::invalid_argument("LoadNXcanSAS: Trying to load multiperiod "
41 "data. This is currently not supported.");
42 }
43 auto objectType = root.getObjTypeByIdx(0);
44 if (objectType != H5G_GROUP) {
45 throw std::invalid_argument("LoadNXcanSAS: The object below the root is not a H5::Group.");
46 }
47
48 return root.getObjnameByIdx(0);
49}
50
55bool findDefinition(Mantid::Nexus::File &file) {
56 bool foundDefinition = false;
57 const auto entries = file.getEntries();
58 for (const auto &[sasEntry, nxEntry] : entries) {
59 if (nxEntry == sasEntryClassAttr || nxEntry == nxEntryClassAttr) {
60 file.openGroup(sasEntry, nxEntry);
61 file.openData(sasEntryDefinition);
62 const auto definitionFromFile = file.getStrData();
63 if (definitionFromFile == sasEntryDefinitionFormat) {
64 foundDefinition = true;
65 break;
66 }
67 file.closeData();
68 file.closeGroup();
69 }
70 }
71 return foundDefinition;
72}
73
74Mantid::API::MatrixWorkspace_sptr createWorkspace(const DataSpaceInformation &dimInfo, const bool asHistogram = false) {
75 const auto &[dimSpectrumAxis, dimBin, _] = dimInfo;
76 // Create a workspace based on the dataSpace information
78 "Workspace2D", dimSpectrumAxis /*NHisto*/, asHistogram ? dimBin + 1 : dimBin /*xdata*/, dimBin /*ydata*/);
79}
80
81std::vector<double> getNumDataSetIfExists(const H5::Group &group, const std::string &datasetName) {
82 if (group.nameExists(datasetName)) {
83 return H5Util::readArray1DCoerce<double>(group, datasetName);
84 }
85 return {};
86}
87
88std::string getStrDataSetIfExists(const H5::Group &group, const std::string &datasetName) {
89 if (group.nameExists(datasetName)) {
90 return H5Util::readString(group, datasetName);
91 }
92 return {};
93}
94
95//----- Logs ----- //
96
97template <typename T>
98void addLogToWs(const MatrixWorkspace_sptr &workspace, const std::string &logName, const T &logValue,
99 const std::string &logUnits = "") {
100 auto &run = workspace->mutableRun();
101 auto property = std::make_unique<PropertyWithValue<T>>(logName, logValue);
102 if (!logUnits.empty()) {
103 property->setUnits(logUnits);
104 }
105 run.addProperty(std::move(property));
106}
107
108void loadLogs(const H5::Group &entry, const MatrixWorkspace_sptr &workspace) {
109 const auto addLogFromGroup = [workspace](const H5::Group &group, const std::string &sasTerm,
110 const std::string &propertyName) {
111 const auto propValue = getStrDataSetIfExists(group, sasTerm);
112 if (!propValue.empty()) {
113 addLogToWs(workspace, propertyName, propValue);
114 }
115 };
116 // Load UserFile, BatchFile and Run if present on file
117 const auto process = entry.openGroup(sasProcessGroupName);
118 addLogFromGroup(process, sasProcessTermUserFile, sasProcessUserFileInLogs);
119 addLogFromGroup(process, sasProcessTermBatchFile, sasProcessBatchFileInLogs);
120 addLogFromGroup(entry, sasEntryRun, sasEntryRunInLogs);
121}
122
123void loadTitle(const H5::Group &entry, const Workspace_sptr &workspace) {
124 if (entry.nameExists(sasEntryTitle)) {
125 workspace->setTitle(H5Util::readString(entry, sasEntryTitle));
126 }
127}
128
129//----- Polarization ----- //
130
135bool checkPolarization(const H5::Group &group) {
136 const auto pIn = group.nameExists(sasDataPin);
137 const auto pOut = group.nameExists(sasDataPout);
138 if (pIn != pOut) {
139 throw std::invalid_argument("Polarized data requires to have Pin and Pout axes");
140 }
141 return pIn;
142}
143
149std::pair<std::vector<int>, std::vector<int>> loadSpinVectors(const H5::Group &group) {
150 // Check for polarization first
151 std::vector<int> pIn;
152 std::vector<int> pOut;
153 if (checkPolarization(group)) {
154 pIn = H5Util::readArray1DCoerce<int>(group, sasDataPin);
155 pOut = H5Util::readArray1DCoerce<int>(group, sasDataPout);
156 }
157 return std::make_pair(pIn, pOut);
158}
159
170std::vector<SpinState> prepareSpinIndexes(const std::vector<int> &pIn, const std::vector<int> &pOut) {
171 // Holds spin pair with vector indexes to iterate hyperslab
172 auto spinToString = [](const int spinIndex) {
173 return spinIndex == 1 ? '+' + std::to_string(spinIndex) : std::to_string(spinIndex);
174 };
175
176 std::vector<SpinState> spinIndexes;
177 for (size_t i = 0; i < pIn.size(); i++) {
178 for (size_t j = 0; j < pOut.size(); j++) {
179 SpinState state;
180 state.strSpinState = spinToString(pIn.at(i)) + spinToString(pOut.at(j));
181 state.spinIndexPair = std::make_pair(i, j);
182 spinIndexes.push_back(std::move(state));
183 }
184 }
185 return spinIndexes;
186}
187
193void loadPolarizedLogs(const H5::Group &group, const MatrixWorkspace_sptr &workspace) {
194 const auto logNames = std::vector({sasSampleEMFieldDirectionAzimuthal, sasSampleEMFieldDirectionPolar,
196 for (const auto &log : logNames) {
197 auto logValue = getNumDataSetIfExists(group, log);
198 if (!logValue.empty()) {
199 std::string logUnits;
200 H5Util::readStringAttribute(group.openDataSet(log), sasUnitAttr, logUnits);
201 addLogToWs(workspace, log, logValue.front(), logUnits);
202 }
203 }
204}
205
206//----- Sample ----- //
207std::optional<H5::Group> getGroupIfExists(const H5::Group &group, const std::string &groupName) {
208 if (group.nameExists(groupName)) {
209 return group.openGroup(groupName);
210 }
211 return std::nullopt;
212}
213
219std::optional<Sample> loadSample(const H5::Group &group) {
220 // Load Height, Width, and Geometry from the aperture group and save to Sample object.
221 const auto &instrumentGroup = getGroupIfExists(group, sasInstrumentGroupName);
222 auto apertureGroup = std::optional<H5::Group>();
223 if (instrumentGroup.has_value()) {
224 apertureGroup = getGroupIfExists(instrumentGroup.value(), sasInstrumentApertureGroupName);
225 }
226 const auto &sampleGroup = getGroupIfExists(group, sasInstrumentSampleGroupAttr);
227
228 if (!apertureGroup.has_value() && !sampleGroup.has_value()) {
229 return std::nullopt;
230 }
231 auto sample = Sample();
232 if (apertureGroup.has_value()) {
233 const auto &height = getNumDataSetIfExists(apertureGroup.value(), sasInstrumentApertureGapHeight);
234 if (!height.empty()) {
235 sample.setHeight(height.front());
236 }
237 const auto &width = getNumDataSetIfExists(apertureGroup.value(), sasInstrumentApertureGapWidth);
238 if (!width.empty()) {
239 sample.setWidth(width.front());
240 }
241 auto geometry = getStrDataSetIfExists(apertureGroup.value(), sasInstrumentApertureShape);
242 boost::to_lower(geometry);
243 if (!geometry.empty()) {
244 SAMPLE_GEOMETRIES.contains(geometry) ? sample.setGeometryFlag(SAMPLE_GEOMETRIES.at(geometry))
245 : sample.setGeometryFlag(0);
246 }
247 }
248
249 // Load thickness from the sample group and save to the Sample object.
250 if (sampleGroup.has_value()) {
251 const auto &thickness = getNumDataSetIfExists(sampleGroup.value(), sasInstrumentSampleThickness);
252 if (!thickness.empty()) {
253 sample.setThickness(thickness.front());
254 }
255 }
256 return sample;
257}
258
264void loadInstrument(const Mantid::API::MatrixWorkspace_sptr &workspace, const InstrumentNameInfo &instrumentInfo) {
265 // Try to load the instrument. If it fails we will continue nevertheless.
266 try {
267 const auto instAlg = Mantid::API::AlgorithmManager::Instance().createUnmanaged("LoadInstrument");
268 instAlg->initialize();
269 instAlg->setChild(true);
270 instAlg->setProperty("Workspace", workspace);
271 instAlg->setProperty("InstrumentName", instrumentInfo.instrumentName);
272 if (!instrumentInfo.idf.empty()) {
273 instAlg->setProperty("Filename", instrumentInfo.idf);
274 }
275 instAlg->setProperty("RewriteSpectraMap", "False");
276 instAlg->execute();
277 } catch (std::invalid_argument &) {
278 g_log.information("Invalid argument to LoadInstrument Child Algorithm.");
279 } catch (std::runtime_error &) {
280 g_log.information("Unable to successfully run LoadInstrument Child Algorithm.");
281 }
282}
283
284//----- Data ----- //
285
305std::vector<hsize_t> updateOffset(const int axesIndex, const std::pair<size_t, size_t> &spinIndexPair,
306 std::vector<hsize_t> &slabShape) {
307 const bool isXAxis = axesIndex == WorkspaceDataAxes::X || axesIndex == WorkspaceDataAxes::XErr;
308 const auto &[indexPin, indexPout] = spinIndexPair;
309 auto position = std::vector<hsize_t>(slabShape.size(), 0);
310 if (slabShape.size() > 2) {
311 if (isXAxis) {
312 // cut slabShape for Q data
313 slabShape = std::vector<hsize_t>(slabShape.cbegin() + 2, slabShape.cend());
314 position = std::vector<hsize_t>(position.cbegin() + 2, position.cend());
315 } else {
316 position.at(0) = indexPin;
317 position.at(1) = indexPout;
318 }
319 }
320 return position;
321}
322
323std::string getStrAttribute(const H5::DataSet &dataSet, const std::string &attrName) {
324 std::string attrValue;
325 H5Util::readStringAttribute(dataSet, attrName, attrValue);
326 return attrValue;
327}
328
333struct WorkspaceDataInserter {
334 explicit WorkspaceDataInserter(MatrixWorkspace_sptr workspace) : workspace(std::move(workspace)), axisType(0) {}
335
336 void insertData(const size_t index, const std::vector<double> &data) const {
337 switch (axisType) {
338 case Y:
339 workspace->mutableY(index) = data;
340 break;
341 case YErr:
342 workspace->mutableE(index) = data;
343 break;
344 case X:
345 workspace->mutableX(index) = data;
346 break;
347 case XErr:
348 workspace->setPointStandardDeviations(index, data);
349 break;
350 default:
351 throw std::runtime_error("Provided axis is not compatible with workspace.");
352 }
353 }
354
355 void setUnits(const H5::DataSet &dataSet) const {
356 if (axisType == Y) {
357 workspace->setYUnit(getStrAttribute(dataSet, sasUnitAttr));
358 } else if (axisType == X) {
359 workspace->getAxis(0)->setUnit("MomentumTransfer");
360 }
361 }
362
363 void setAxisType(const int type) { axisType = type; }
365 int axisType;
366};
367
377void readDataIntoWorkspace(const H5::DataSet &dataSet, const WorkspaceDataInserter &inserter,
378 const std::vector<hsize_t> &slabShape, const hsize_t nPoints, const hsize_t nHistograms,
379 std::vector<hsize_t> &offset) {
380
381 // Memory Data Space
382 const std::array<hsize_t, 1> memSpaceDimension = {nPoints};
383 const H5::DataSpace memSpace(1, memSpaceDimension.data());
384 const bool isPolarizedDataSet = slabShape.size() > 2;
385 const auto histogramIndex = isPolarizedDataSet ? slabShape.size() - 2 : 0;
386
387 const auto fileSpace = dataSet.getSpace();
388 auto data = std::vector<double>(nPoints, 0);
389 for (size_t index = 0; index < nHistograms; ++index) {
390 // Set the dataSpace to a 1D HyperSlab
391 fileSpace.selectHyperslab(H5S_SELECT_SET, slabShape.data(), offset.data());
392 dataSet.read(data.data(), H5Util::getType<double>(), memSpace, fileSpace);
393 inserter.insertData(index, data);
394 offset.at(histogramIndex)++;
395 }
396}
397
405void readQyInto2DWorkspace(const H5::DataSet &dataSet, const Mantid::API::MatrixWorkspace_sptr &workspace,
406 const hsize_t nHistograms) {
407 // Size of single slab
408 const std::array<hsize_t, 2> slabShape = {nHistograms, 1};
409 const std::array<hsize_t, 2> position = {0, 0};
410
411 // Memory Data Space
412 const std::array<hsize_t, 1> memSpaceDimensions = {nHistograms};
413 const H5::DataSpace memSpace(1, memSpaceDimensions.data());
414
415 // Select the HyperSlab
416 const auto fileSpace = dataSet.getSpace();
417 fileSpace.selectHyperslab(H5S_SELECT_SET, slabShape.data(), position.data());
418
419 // Read the data
420 auto data = std::vector<double>(nHistograms);
421 dataSet.read(data.data(), H5Util::getType<double>(), memSpace, fileSpace);
422
423 auto newAxis = std::make_unique<Mantid::API::NumericAxis>(data);
424 workspace->replaceAxis(1, std::move(newAxis));
425
426 // Set the axis units
427 workspace->getAxis(1)->setUnit("MomentumTransfer");
428}
429
430//----- Transmission ----- //
431bool fileHasTransmissionEntry(const H5::Group &entry, const std::string &name) {
432 const bool hasTransmission = entry.nameExists(sasTransmissionSpectrumGroupName + "_" + name);
433 if (!hasTransmission) {
434 g_log.information("NXcanSAS file does not contain transmission for " + name);
435 }
436 return hasTransmission;
437}
438
444void loadTransmissionData(const H5::Group &transmission, const Mantid::API::MatrixWorkspace_sptr &workspace) {
445 //-----------------------------------------
446 // Load T
447 workspace->mutableY(0) = H5Util::readArray1DCoerce<double>(transmission, sasTransmissionSpectrumT);
448 //-----------------------------------------
449 // Load Tdev
450 workspace->mutableE(0) = H5Util::readArray1DCoerce<double>(transmission, sasTransmissionSpectrumTdev);
451 //-----------------------------------------
452 // Load Lambda. A bug in older versions (fixed in 6.0) allowed the
453 // transmission lambda points to be saved as bin edges rather than points as
454 // required by the NXcanSAS standard. We allow loading those files and convert
455 // to points on the fly
456 std::vector<double> lambda;
458 if (lambda.size() == workspace->blocksize())
459 workspace->setPoints(0, std::move(lambda));
460 else if (lambda.size() == workspace->blocksize() + 1)
461 workspace->setBinEdges(0, std::move(lambda));
462 else {
463 const std::string objectName{transmission.getObjName()};
464 throw std::runtime_error("Unexpected array size for lambda in transmission group '" + objectName +
465 "'. Expected length=" + std::to_string(workspace->blocksize()) +
466 ", found length=" + std::to_string(lambda.size()));
467 }
468 workspace->getAxis(0)->setUnit("Wavelength");
469 workspace->setYUnitLabel("Transmission");
470 // Set to distribution
471 workspace->setDistribution(true);
472}
473
474} // namespace
475
477// Register the algorithm into the AlgorithmFactory
479
480
482
484 const std::string &extn = descriptor.extension();
485 if (extn != ".nxs" && extn != ".h5") {
486 return 0;
487 }
488 int confidence = 0;
489 Mantid::Nexus::File file(descriptor.filename());
490 // Check if there is an entry root/SASentry/definition->NXcanSAS
491 try {
492 if (findDefinition(file)) {
493 confidence = 95;
494 }
495 } catch (...) {
496 }
497
498 return confidence;
499}
500
502 // Declare required input parameters for algorithm
503 const std::vector<std::string> exts{".nxs", ".h5"};
504 declareProperty(std::make_unique<Mantid::API::FileProperty>("Filename", "", FileProperty::Load, exts),
505 "The name of the NXcanSAS file to read, as a full or relative path.");
506 declareProperty(std::make_unique<Mantid::API::WorkspaceProperty<Mantid::API::Workspace>>("OutputWorkspace", "",
508 "The name of the workspace to be created as the output of "
509 "the algorithm. A workspace of this name will be created "
510 "and stored in the Analysis Data Service. For multiperiod "
511 "files, one workspace may be generated for each period. "
512 "Currently only one workspace can be saved at a time so "
513 "multiperiod Mantid files are not generated.");
514
515 declareProperty(std::make_unique<PropertyWithValue<bool>>("LoadTransmission", false, Direction::Input),
516 "Load the transmission related data from the file if it is present "
517 "(optional, default False).");
518}
519
521 const std::string fileName = getPropertyValue("Filename");
522 const bool isLoadTransmissionChecked = getProperty("LoadTransmission");
523 H5::H5File file(fileName, H5F_ACC_RDONLY, Nexus::H5Util::defaultFileAcc());
524
525 const auto entry = file.openGroup(getNameOfEntry(file));
526 const auto dataGroup = entry.openGroup(sasDataGroupName);
527 const auto dataInfo = getDataSpaceInfo(dataGroup.openDataSet(sasDataI));
528
529 // Setup progress bar
530 const size_t stepsPerSpinState = dataInfo.spinStates * 5;
531 const auto numberOfSteps = isLoadTransmissionChecked ? stepsPerSpinState + 1 : stepsPerSpinState;
532 m_progress = std::make_unique<API::Progress>(this, 0.1, 1.0, numberOfSteps);
533
534 // Load metadata and data into output workspace
535 const InstrumentNameInfo instrumentInfo(entry);
536 const auto wsGroup = transferFileDataIntoWorkspace(entry, dataInfo, instrumentInfo);
537
538 // Load Transmissions
539 if (isLoadTransmissionChecked) {
540 m_progress->report("Loading transmissions.");
541 // Load sample transmission
543 // Load can transmission
545 }
546
547 const auto wsOut = dataInfo.spinStates == 1 ? wsGroup->getItem(0) : std::dynamic_pointer_cast<Workspace>(wsGroup);
548 file.close();
549 setProperty("OutputWorkspace", wsOut);
550}
551
561 const InstrumentNameInfo &instrumentInfo, const std::optional<Sample> &sample,
562 const bool hasPolarizedData) const {
563 // Load logs
564 m_progress->report("Loading logs.");
565 loadLogs(group, workspace);
566 if (hasPolarizedData && group.nameExists(sasInstrumentSampleGroupAttr)) {
567 loadPolarizedLogs(group.openGroup(sasInstrumentSampleGroupAttr), workspace);
568 }
569
570 // Load title
571 m_progress->report("Loading title");
572 loadTitle(group, workspace);
573
574 // Load sample info
575 m_progress->report("Loading sample.");
576 if (sample.has_value()) {
577 workspace->mutableSample() = sample.value();
578 }
579 // Load instrument
580 m_progress->report("Loading instrument.");
581 loadInstrument(workspace, instrumentInfo);
582}
583
591 const std::pair<size_t, size_t> &spinIndexPair) const {
592 m_progress->report("Loading data.");
593 workspace->setDistribution(true);
594 WorkspaceDataInserter dataInserter(workspace);
595 auto dataSets = std::map<std::string, int>{
596 {sasDataI, 0}, {sasDataIdev, 1}, {m_dataDims->getNumberOfHistograms() > 1 ? sasDataQx : sasDataQ, 2}};
597
598 if (dataGroup.nameExists(sasDataQdev)) {
599 dataSets.insert({sasDataQdev, 3});
600 }
601 auto slabShape = m_dataDims->getSlabShape();
602 const auto nPoints = m_dataDims->getNumberOfPoints();
603 const auto nHisto = m_dataDims->getNumberOfHistograms();
604
605 for (const auto &[setName, axesIndex] : dataSets) {
606 auto dataSet = dataGroup.openDataSet(setName);
607 auto offset = updateOffset(axesIndex, spinIndexPair, slabShape);
608 dataInserter.setAxisType(axesIndex);
609 readDataIntoWorkspace(dataSet, dataInserter, slabShape, nPoints, nHisto, offset);
610 dataInserter.setUnits(dataSet);
611 }
612
613 // Qy is inserted a bit differently
614 if (dataGroup.nameExists(sasDataQy)) {
615 readQyInto2DWorkspace(dataGroup.openDataSet(sasDataQy), workspace, m_dataDims->getNumberOfHistograms());
616 }
617}
618
625std::vector<SpinState> LoadNXcanSAS::prepareDataDimensions(const H5::Group &group,
626 const DataSpaceInformation &dataInfo) {
627 const auto &[pIn, pOut] = loadSpinVectors(group);
628 const auto spinPairs =
629 !pIn.empty() && !pOut.empty() ? std::optional(std::make_pair(pIn.size(), pOut.size())) : std::nullopt;
630
631 const auto spinStates = spinPairs.has_value() ? prepareSpinIndexes(pIn, pOut) :
632 /* default unpolarized: 1 state */ std::vector({SpinState()});
633 // prepare data dimensions and offset
634 m_dataDims = std::make_unique<DataDimensions>(dataInfo.dimBin, dataInfo.dimSpectrumAxis, spinPairs);
635 return spinStates;
636}
637
646 const DataSpaceInformation &dataInfo,
647 const InstrumentNameInfo &instrumentInfo) {
648 const auto dataGroup = group.openGroup(sasDataGroupName);
649 const auto states = prepareDataDimensions(dataGroup, dataInfo);
650 const auto wsName = getPropertyValue("OutputWorkspace");
651
652 auto dataOut = std::make_shared<WorkspaceGroup>();
653 const auto sample = loadSample(group); // Sample should be similar in all workspaces
654 // spinStr will be empty if data is not polarized -> Only one output workspace
655 for (const auto &[spinStr, spinIndexPair] : states) {
656 auto ws = createWorkspace(dataInfo);
657
658 loadMetadata(group, ws, instrumentInfo, sample, !spinStr.empty());
659 loadData(dataGroup, ws, spinIndexPair);
660
661 if (!spinStr.empty()) {
662 addLogToWs(ws, NX_SPIN_LOG, spinStr);
663 ws->setTitle(wsName + "_" + spinStr);
664 }
665 dataOut->addWorkspace(ws);
666 }
667 return dataOut;
668}
669
670void LoadNXcanSAS::loadTransmission(const H5::Group &entry, const std::string &name,
671 const InstrumentNameInfo &instrumentInfo) {
672 if (!fileHasTransmissionEntry(entry, name)) {
673 return;
674 }
675 const auto transmission = entry.openGroup(sasTransmissionSpectrumGroupName + "_" + name);
676 const auto tDataSet = transmission.openDataSet(sasTransmissionSpectrumT);
677 // Create a 1D workspace
678 const auto workspace = createWorkspace(getDataSpaceInfo(tDataSet), true);
679 // Load logs
680 loadLogs(entry, workspace);
681 loadTitle(entry, workspace);
682 workspace->setTitle(workspace->getTitle() + "_trans_" + name);
683 // Load Instrument
684 loadInstrument(workspace, instrumentInfo);
685 // Load transmission data
686 loadTransmissionData(transmission, workspace);
687 // Set the workspace on the output
688 const std::string propertyName = (name == "sample") ? "TransmissionWorkspace" : "TransmissionCanWorkspace";
689 declareProperty(std::make_unique<WorkspaceProperty<>>(propertyName, workspace->getTitle(), Direction::Output),
690 "The transmission workspace");
691 setProperty(propertyName, workspace);
692}
693
694} // namespace Mantid::DataHandling::NXcanSAS
std::string name
Definition Run.cpp:60
const std::vector< double > * lambda
double height
Definition GetAllEi.cpp:155
double position
Definition GetAllEi.cpp:154
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
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.
@ Load
allowed here which will be passed to the algorithm
This class stores information about the sample used in particular run.
Definition Sample.h:33
A property class for workspaces.
LoadNXcanSAS : Tries to load an NXcanSAS file type into a Workspace2D.
int confidence(Nexus::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void loadMetadata(const H5::Group &group, const Mantid::API::MatrixWorkspace_sptr &workspace, const InstrumentNameInfo &instrumentInfo, const std::optional< API::Sample > &sample, bool hasPolarizedData=false) const
Loads metadata from H5 File into a Workspace: sample logs, instrument and sample information.
void loadData(const H5::Group &dataGroup, const Mantid::API::MatrixWorkspace_sptr &workspace, const std::pair< size_t, size_t > &spinIndexPair) const
General data loader, uses m_dataDims.
std::unique_ptr< NXcanSAS::DataDimensions > m_dataDims
void init() override
Initialisation code.
const std::string name() const override
function to return a name of the algorithm, must be overridden in all algorithms
void loadTransmission(const H5::Group &entry, const std::string &name, const InstrumentNameInfo &instrumentInfo)
Loads the transmission runs.
Mantid::API::WorkspaceGroup_sptr transferFileDataIntoWorkspace(const H5::Group &group, const DataSpaceInformation &dataInfo, const InstrumentNameInfo &instrumentInfo)
Prepares data to be loaded based on type and dimensionality.
std::unique_ptr< API::Progress > m_progress
std::vector< SpinState > prepareDataDimensions(const H5::Group &group, const DataSpaceInformation &dataInfo)
Prepares the DataDimensions struct that contains the shapes of the dataset objects,...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
const std::string & extension() const
Access the file extension.
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
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< T > createWorkspace(InitArgs... args)
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
const std::string sasInstrumentApertureGapWidth
const std::string sasTransmissionSpectrumNameCanAttrValue
const std::string sasInstrumentApertureGapHeight
const std::string sasTransmissionSpectrumTdev
DataSpaceInformation getDataSpaceInfo(const H5::DataSet &dataSet)
const std::string sasSampleEMFieldDirectionAzimuthal
const std::string sasTransmissionSpectrumLambda
const std::string sasInstrumentSampleThickness
const std::string sasTransmissionSpectrumNameSampleAttrValue
const std::string sasInstrumentApertureGroupName
const std::string sasSampleEMFieldDirectionRotation
const std::string sasTransmissionSpectrumGroupName
const std::string sasInstrumentSampleGroupAttr
const std::string sasSampleEMFieldDirectionPolar
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 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)
MANTID_NEXUS_DLL DataType getType< double >()
Definition H5Util.cpp:40
Header for a base Nexus::Exception.
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
std::pair< size_t, size_t > spinIndexPair
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54