13#include "MantidIndexing/IndexInfo.h"
15#include "MantidNexusGeometry/AbstractLogger.h"
16#include "MantidNexusGeometry/NexusGeometryParser.h"
17#include "MantidTypes/SpectrumDefinition.h"
31template <
typename T>
int countEntriesOfType(
const T &entry,
const std::string &nxClass) {
32 return static_cast<int>(std::count_if(entry.groups().cbegin(), entry.groups().cend(),
33 [&nxClass](
const auto &group) { return group.nxclass == nxClass; }));
37std::vector<Mantid::NeXus::NXClassInfo> findEntriesOfType(
const T &entry,
const std::string &nxClass) {
38 std::vector<Mantid::NeXus::NXClassInfo> result;
39 std::copy_if(entry.groups().cbegin(), entry.groups().cend(), std::back_inserter(result),
40 [&nxClass](
const auto &group) { return group.nxclass == nxClass; });
52 const auto instrumentsCount = countEntriesOfType(entry,
"NXinstrument");
53 if (instrumentsCount == 1) {
59 if (instr.containsGroup(
"detector") ||
60 (instr.containsGroup(
"physical_detectors") && instr.containsGroup(
"physical_monitors"))) {
88 g_log.
information() <<
"Instrument layout not recognised. Spectra mappings not loaded.";
93 auto result = findEntriesOfType(mtd_entry,
"NXinstrument");
94 if (result.size() != 1) {
95 g_log.
warning(
"We are expecting a single NXinstrument. No mappings loaded");
102 for (
const auto &group : inst.groups()) {
103 if (group.nxclass ==
"NXdetector" || group.nxclass ==
"NXmonitor") {
104 NXDetector detgroup = inst.openNXDetector(group.nxname);
108 spectra_block.
load();
109 }
catch (std::runtime_error &) {
113 const size_t nSpecEntries = spectra_block.
dim0();
115 size_t currentSize = spectrumNumbers.size();
116 spectrumNumbers.resize(currentSize + nSpecEntries, 0);
118 for (
size_t i = 0; i < nSpecEntries; ++i) {
119 spectrumNumbers[i + currentSize] = data[i];
124 size_t nDetEntries = det_index.
dim0();
125 currentSize = detectorIds.size();
127 detectorIds.resize(currentSize + nDetEntries, 0);
128 for (
size_t i = 0; i < nDetEntries; ++i) {
129 detectorIds[i + currentSize] = data[i];
135 size_t nDetCounts = det_counts.
dim0();
136 currentSize = detectorCounts.size();
138 detectorCounts.resize(currentSize + nDetCounts, 0);
140 for (
size_t i = 0; i < nDetCounts; ++i) {
141 const int dataVal = data[i];
143 detectorCounts[i + currentSize] = dataVal;
146 if (nDetCounts != nSpecEntries) {
147 throw std::runtime_error(
"Bad file. Has different number of entries in "
148 "spec and detector_count datasets");
150 if (dataSum != nDetEntries) {
151 throw std::runtime_error(
"Bad file. detector_counts sum does not match "
152 "the number of detectors given by number of "
153 "detector_list entries");
180 const std::string &filename) {
186 NexusGeometry::NexusGeometryParser::createInstrument(filename, NexusGeometry::makeLogger(&logger));
189 auto &detInfo = matrixWs->detectorInfo();
191 std::vector<SpectrumDefinition> definitions;
193 size_t detCounter = 0;
197 SpectrumDefinition def;
200 for (
size_t j = 0; j < counts; ++j, ++detCounter) {
203 definitions.emplace_back(def);
205 info.setSpectrumDefinitions(definitions);
206 matrixWs->setIndexInfo(info);
208 }
catch (std::exception &e) {
210 }
catch (H5::Exception &e) {
211 logger.
warning(e.getDetailMsg());
219 if (descriptor.
pathExists(
"/mantid_workspace_1"))
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
Base MatrixWorkspace Abstract Class.
A property class for workspaces.
Base Workspace Abstract Class.
void extractMappingInfoNew(const Mantid::NeXus::NXEntry &mtd_entry)
Extract mapping information where it is build across NXDetectors.
void readSpectraToDetectorMapping(Mantid::NeXus::NXEntry &mtd_entry, Mantid::API::MatrixWorkspace &ws) override
InstrumentLayout m_instrumentLayout
Load nexus geometry and apply to workspace Local caches.
int confidence(Kernel::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
int version() const override
Algorithm's version for identification.
bool loadNexusGeometry(Mantid::API::Workspace &ws, const int nWorkspaceEntries, Kernel::Logger &logger, const std::string &filename) override
Attempt to load nexus geometry.
std::vector< int > m_detectorCounts
std::vector< Indexing::SpectrumNumber > m_spectrumNumbers
const std::string name() const override
Algorithms name for identification.
std::vector< Mantid::detid_t > m_detectorIds
int confidence(Kernel::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void readInstrumentGroup(Mantid::NeXus::NXEntry &mtd_entry, API::MatrixWorkspace &local_workspace)
Read the spectra.
The Logger class is in charge of the publishing messages from the framework through various channels.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
bool pathExists(const std::string &path) const
Query if a path exists.
NXInt openNXInt(const std::string &name) const
Creates and opens an integer dataset.
void close()
Close this class.
bool containsGroup(const std::string &query) const
Returns whether an individual group (or group) is present.
Templated class implementation of NXDataSet.
container_T< T > & vecBuffer()
Returns a the internal buffer.
void load(const int blocksize=1, int i=-1, int j=-1, int k=-1, int l=-1) override
Implementation of the virtual NXDataSet::load(...) method.
int dim0() const
Returns the number of elements along the first dimension.
Implements NXdetector Nexus class.
Implements NXentry Nexus class.
NXInstrument openNXInstrument(const std::string &name) const
Opens a NXInstrument.
Kernel::Logger g_log("ExperimentInfo")
static logger object
InstrumentLayout
Layout information relating to detector-spectra mappings.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
Describes the direction (within an algorithm) of a Property.