diff --git a/include/openPMD/CustomHierarchy.hpp b/include/openPMD/CustomHierarchy.hpp index dc23a97e64..55bc6361de 100644 --- a/include/openPMD/CustomHierarchy.hpp +++ b/include/openPMD/CustomHierarchy.hpp @@ -228,10 +228,21 @@ class CustomHierarchy : public ConversibleContainer CustomHierarchy(); CustomHierarchy(NoInit); - void read(internal::MeshesParticlesPath const &); + inline void setData(std::shared_ptr data) + { + m_customHierarchyData = data; + Container_t::setData(std::move(data)); + } + + void read( + internal::MeshesParticlesPath const &, + Container meshes, + Container particles); void read( internal::MeshesParticlesPath const &, - std::vector ¤tPath); + std::vector ¤tPath, + Container meshes, + Container particles); void flush_internal( internal::FlushParams const &, diff --git a/src/CustomHierarchy.cpp b/src/CustomHierarchy.cpp index 1dc0fb1788..2fb2ab6e56 100644 --- a/src/CustomHierarchy.cpp +++ b/src/CustomHierarchy.cpp @@ -376,15 +376,45 @@ void CustomHierarchy::readParticleSpecies( } } -void CustomHierarchy::read(internal::MeshesParticlesPath const &mpp) +void CustomHierarchy::read( + internal::MeshesParticlesPath const &mpp, + Container meshes, + Container particles) { std::vector currentPath; - read(mpp, currentPath); + read(mpp, currentPath, meshes, particles); } +namespace +{ + template + void add_to_meshes_particles_view( + std::vector const ¤tPath, + std::string const &defaultMeshesParticlesPath, + Container &meshesOrParticles, + std::string const &name, + T &meshOrParticle) + { + if (currentPath.empty()) + { + throw std::runtime_error( + "Meshes or particles cannot be part of the root group."); + } + auto concatenatedName = concatWithSep(currentPath, "/"); + concatenatedName.append(1, '/').append(name); + meshesOrParticles[concatenatedName] = meshOrParticle; + if (concatenatedName == defaultMeshesParticlesPath + '/' + name) + { + meshesOrParticles[name] = meshOrParticle; + } + } +} // namespace + void CustomHierarchy::read( internal::MeshesParticlesPath const &mpp, - std::vector ¤tPath) + std::vector ¤tPath, + Container meshes, + Container particles) { /* * Convention for CustomHierarchy::flush and CustomHierarchy::read: @@ -416,7 +446,7 @@ void CustomHierarchy::read( currentPath.emplace_back(path); try { - subpath.read(mpp, currentPath); + subpath.read(mpp, currentPath, meshes, particles); } catch (error::ReadError const &err) { @@ -442,6 +472,12 @@ void CustomHierarchy::read( try { readNonscalarMesh(meshesMap, path); + add_to_meshes_particles_view( + currentPath, + mpp.m_defaultMeshesPath, + meshes, + path, + meshesMap[path]); } catch (error::ReadError const &err) { @@ -451,12 +487,19 @@ void CustomHierarchy::read( << err.what() << std::endl; meshesMap.forget(path); } + break; } case internal::ContainedType::Particle: { try { readParticleSpecies(particlesMap, path); + add_to_meshes_particles_view( + currentPath, + mpp.m_defaultParticlesPath, + particles, + path, + particlesMap[path]); } catch (error::ReadError const &err) { @@ -514,12 +557,18 @@ void CustomHierarchy::read( try { readScalarMesh(meshesMap, path); + add_to_meshes_particles_view( + currentPath, + mpp.m_defaultMeshesPath, + meshes, + path, + meshesMap[path]); } catch (error::ReadError const &err) { - std::cerr << "Cannot read scalar mesh at location '" + std::cerr << "Cannot read mesh at location '" << myPath().openPMDPath() << "/" << path - << "' and will skip it due to read error:\n" + << "' and will skip them due to read error:\n" << err.what() << std::endl; meshesMap.forget(path); } diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 0125df5973..a090ec9f1a 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -395,9 +395,9 @@ void Iteration::sync_meshes_and_particles_from_alias_to_subgroups( { if (auxiliary::contains(name, '/')) { - throw std::runtime_error( - "Unimplemented: Multi-level paths in " - "Iteration::meshes/Iteration::particles"); + // throw std::runtime_error( + // "Unimplemented: Multi-level paths in " + // "Iteration::meshes/Iteration::particles"); } if (auto it = container.find(name); it != container.end()) { @@ -592,9 +592,7 @@ void Iteration::read_impl(std::string const &groupPath) // hasMeshes <-> meshesPath is defined internal::MeshesParticlesPath mpp(s.meshesPaths(), s.particlesPaths()); - CustomHierarchy::read(mpp); - - sync_meshes_and_particles_from_subgroups_to_alias(mpp); + CustomHierarchy::read(mpp, meshes, particles); #ifdef openPMD_USE_INVASIVE_TESTS if (containsAttribute("__openPMD_internal_fail"))