13#include <boost/multi_index/detail/index_matcher.hpp>
21using boost::multi_index::detail::index_matcher::entry;
29void getGroup(H5::Group groupID, std::map<std::string, std::set<std::string>> &allEntries,
30 std::pair<std::string, std::string> &firstEntryNameType,
size_t level) {
35 auto lf_getNxClassAttribute = [&](H5::Group groupID) -> std::string {
36 std::string attribute =
"";
38 if (groupID.attrExists(
"NX_class")) {
39 const auto attributeID = groupID.openAttribute(
"NX_class");
40 attributeID.read(attributeID.getDataType(), attribute);
47 const std::string groupNameStr = groupID.getObjName();
48 const std::string nxClass = (groupNameStr ==
"/") ?
"" : lf_getNxClassAttribute(groupID);
50 if (!nxClass.empty()) {
51 allEntries[nxClass].insert(groupNameStr);
54 for (
hsize_t i = 0; i < groupID.getNumObjs(); ++i) {
56 H5G_obj_t type = groupID.getObjTypeByIdx(i);
57 H5std_string memberName = groupID.getObjnameByIdx(i);
59 if (type == H5G_GROUP) {
60 H5::Group subGroupID = groupID.openGroup(memberName);
62 firstEntryNameType = std::make_pair(memberName, lf_getNxClassAttribute(subGroupID));
63 getGroup(subGroupID, allEntries, firstEntryNameType, level + 1);
64 }
else if (type == H5G_DATASET) {
65 allEntries[
"SDS"].emplace(groupNameStr +
"/" + memberName);
74 : m_filename(filename), m_extension(
std::filesystem::path(m_filename).extension().string()), m_firstEntryNameType(),
75 m_allEntries(initAllEntries()) {}
78 : m_filename(filename), m_extension(
std::filesystem::path(m_filename).extension().string()),
79 m_firstEntryNameType() {
101 if (entryName.empty())
103 if (groupClass.empty())
105 if (!entryName.starts_with(
"/"))
113 const auto lastPos = entryName.rfind(
"/");
114 const auto parentAddress = entryName.substr(0, lastPos);
115 if (parentAddress !=
"" && !this->
isEntry(parentAddress))
125 std::map<std::string, std::set<std::string>> allEntries;
132 throw std::invalid_argument(
"ERROR: Kernel::NexusDescriptor couldn't open hdf5 file " +
m_filename +
"\n");
136 H5::Group groupID = fileID.openGroup(
"/");
139 for (
int i = 0; i < groupID.getNumAttrs(); ++i) {
140 H5::Attribute attr = groupID.openAttribute(i);
159 auto itClass = m_allEntries.find(groupClass);
160 if (itClass == m_allEntries.end()) {
164 if (itClass->second.count(entryName) == 1) {
172 return std::any_of(m_allEntries.rbegin(), m_allEntries.rend(),
173 [&entryName](
const auto &entry) { return entry.second.count(entryName) == 1; });
177 std::vector<std::string> result;
179 result.assign(itClass->second.begin(), itClass->second.end());
186 std::map<std::string, std::string> result;
188 for (
auto itEntry = itClass->second.cbegin(); itEntry != itClass->second.cend(); itEntry++) {
189 if (itEntry->size() <= level.size()) {
192 if (itEntry->starts_with(level)) {
193 int offset = (level ==
"/" ? 0 : 1);
194 std::string address = itEntry->substr(level.size() + offset, itEntry->find(
"/", level.size() + offset));
195 if (itEntry->ends_with(address)) {
196 result[address] = itClass->first;
207 std::string groupClass;
210 if (it->second.count(entryName) == 1) {
211 groupClass = it->first;
NXaccess
Nexus file access codes.
Class that provides for a standard Nexus exception.
bool classTypeExists(const std::string &classType) const
Query if a given type exists somewhere in the file.
const std::map< std::string, std::set< std::string > > & getAllEntries() const noexcept
Returns a const reference of the internal map holding all entries in the Nexus HDF5 file.
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.
std::string classTypeForName(std::string const &name) const
std::pair< std::string, std::string > m_firstEntryNameType
First entry name/type.
std::vector< std::string > allAddressesOfType(const std::string &type) const
const std::string & filename() const noexcept
Returns a copy of the current file name.
std::map< std::string, std::set< std::string > > initAllEntries()
Sets m_allEntries, called in HDF5 constructor.
std::string m_filename
Nexus HDF5 file name.
std::map< std::string, std::string > allAddressesAtLevel(const std::string &level) const
void addRootAttr(const std::string &name)
std::unordered_set< std::string > m_rootAttrs
Root attributes.
void addEntry(const std::string &entryName, const std::string &groupClass)
Add an entry to the mapping for the file.
bool hasRootAttr(const std::string &name) const
Query if the given attribute exists on the root node.
std::map< std::string, std::set< std::string > > m_allEntries
All entries metadata.
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
Header for a base Nexus::Exception.