23#include <unordered_set>
29static std::unordered_set<std::string>
const SPECIAL_ADDRESS{
"/entry",
"/entry0",
"/entry1",
"/raw_data_1"};
39 if (H5Tis_variable_str(atype)) {
41 char *rdata =
nullptr;
42 if (H5Aread(attrID, atype, &rdata) >= 0) {
43 nxClass = std::string(rdata);
49 std::size_t size = H5Tget_size(atype);
51 H5Aread(attrID, atype, nxClass.data());
64 : m_filename(filename), m_extension(
std::filesystem::path(m_filename).extension().string()), m_firstEntryNameType(),
65 m_allEntries(initAllEntries()), m_allMisses() {}
69 bool known_miss =
false, known_hit =
false;
79 }
else if (known_hit) {
83 if (H5Oexists_by_name(
m_fileID, entryName.c_str(), H5P_DEFAULT) > 0) {
89 H5Oget_info(entryID, &oinfo, H5O_INFO_BASIC);
90 if (oinfo.type == H5O_TYPE_DATASET) {
94 nxclass = readNXClass(entryID);
116 [&classType](
auto const &entry) { return entry.second == classType; });
121 if (!this->
isEntry(parentPath))
128 const auto delimitedEntryName = parentPath +
'/';
131 if (cls == classType &&
name.starts_with(delimitedEntryName)) {
139 bool known_hit =
false;
166 H5::DataSet dataset(did);
167 H5::DataType dtype = dataset.getDataType();
168 if (dtype.isVariableStr() || dtype.getClass() == H5T_STRING) {
169 dataset.read(strData, dtype, dataset.getSpace());
178 unsigned int depth,
const unsigned int maxDepth) {
185 allEntries[address] = readNXClass(groupID);
187 if (depth >= maxDepth)
192 H5Gget_num_objs(groupID.
get(), &numObjs);
193 for (
hsize_t i = 0; i < numObjs; i++) {
194 H5G_obj_t type = H5Gget_objtype_by_idx(groupID, i);
195 ssize_t name_len = H5Gget_objname_by_idx(groupID, i,
nullptr, 0);
198 std::string memberName(name_len,
'X');
199 H5Gget_objname_by_idx(groupID, i, memberName.data(), name_len + 1);
200 std::string memberAddress = address;
201 if (!memberAddress.ends_with(
"/"))
202 memberAddress +=
"/";
203 memberAddress += memberName;
205 if (type == H5G_GROUP) {
206 loadGroups(allEntries, memberAddress, depth + 1, maxDepth);
207 }
else if (type == H5G_DATASET) {
215 H5Eset_auto(H5E_DEFAULT,
nullptr,
nullptr);
217 std::map<std::string, std::string> allEntries;
224 throw std::invalid_argument(
"ERROR: NexusDescriptorLazy couldn't open hdf5 file " +
m_filename +
"\n");
229 throw std::invalid_argument(
"ERROR: NexusDescriptorLazy couldn't open hdf5 file " +
m_filename +
"\n");
233 unsigned int depth = 0;
236 if (allEntries.size() > 1) {
246 if (allEntries.contains(specialAddress))
253 if (allEntries.contains(specialAddress)) {
254 std::string instrumentAddress = specialAddress +
"/instrument";
255 if (allEntries.contains(instrumentAddress)) {
static unsigned int const INSTR_DEPTH
static unsigned int const ENTRY_DEPTH
static std::unordered_set< std::string > const SPECIAL_ADDRESS
static unsigned int const INIT_DEPTH
static std::string const UNKNOWN_CLASS
bool isValid() const
Return whether the UniqueId corresponds to a valid HDF5 object.
hid_t get() const
Return the managed HDF5 handle.
bool classTypeExistsChild(const std::string &parentPath, const std::string &classType) const
Query if a given type exists as a decendant of the supplied parentPath.
std::string const m_filename
Nexus HDF5 file name.
std::string getStrData(std::string const &address)
Get string data from a dataset at address.
std::unordered_set< std::string > m_allMisses
the set of non-existent entries that have been checked
std::pair< std::string, std::string > m_firstEntryNameType
std::shared_mutex m_readNexusMutex
mutex to protect reading from file after initialization in const methods
std::unordered_set< std::string > m_rootAttrs
Root attributes cache.
void loadGroups(std::map< std::string, std::string > &allEntries, std::string const &address, unsigned int depth, const unsigned int maxDepth)
bool hasRootAttr(std::string const &name) const
Query if the given attribute exists on the root node.
bool isEntry(std::string const &entryName, std::string const &groupClass) const
Checks if a full-address entry exists for a particular groupClass in a Nexus dataset.
bool classTypeExists(std::string const &classType) const
Query if a given type exists somewhere in the file.
NexusDescriptorLazy()=delete
std::map< std::string, std::string > m_allEntries
All entries metadata.
std::map< std::string, std::string > initAllEntries()
Sets m_allEntries, called in HDF5 constructor.
UniqueID<&H5Fclose > m_fileID
HDF5 File Handle.
A wrapper class for managing HDF5 object handles (hid_t).
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
Header for a base Nexus::Exception.
std::string const SCIENTIFIC_DATA_SET("SDS")
std::string const GROUP_CLASS_SPEC("NX_class")