Skip to content

Commit 980d42c

Browse files
committed
Move reading logic to CustomHierarchy::read
1 parent 99fec36 commit 980d42c

File tree

8 files changed

+272
-179
lines changed

8 files changed

+272
-179
lines changed

include/openPMD/CustomHierarchy.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,17 @@ namespace internal
3939
{
4040
struct MeshesParticlesPath
4141
{
42-
std::set<std::string> paths;
42+
std::optional<std::string> meshesPath;
43+
std::optional<std::string> particlesPath;
4344
[[nodiscard]] bool ignore(std::string const &name) const;
45+
[[nodiscard]] inline bool hasMeshes() const noexcept
46+
{
47+
return meshesPath.has_value();
48+
}
49+
[[nodiscard]] inline bool hasParticles() const noexcept
50+
{
51+
return particlesPath.has_value();
52+
}
4453
};
4554

4655
struct CustomHierarchyData : ContainerData<CustomHierarchy>
@@ -74,6 +83,9 @@ class CustomHierarchy : public Container<CustomHierarchy>
7483
return *m_customHierarchyData;
7584
}
7685

86+
void readMeshes(std::string const &meshesPath);
87+
void readParticles(std::string const &particlesPath);
88+
7789
protected:
7890
CustomHierarchy();
7991
CustomHierarchy(NoInit);

include/openPMD/Iteration.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,6 @@ class Iteration : public CustomHierarchy
305305
std::string filePath, std::string const &groupPath, bool beginStep);
306306
void readGorVBased(std::string const &groupPath, bool beginStep);
307307
void read_impl(std::string const &groupPath);
308-
void readMeshes(std::string const &meshesPath);
309-
void readParticles(std::string const &particlesPath);
310308

311309
/**
312310
* Status after beginning an IO step. Currently includes:

include/openPMD/Mesh.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Mesh : public BaseRecord<MeshRecordComponent>
4141
{
4242
friend class Container<Mesh>;
4343
friend class Iteration;
44+
friend class CustomHierarchy;
4445

4546
public:
4647
Mesh(Mesh const &) = default;

include/openPMD/backend/Attributable.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class Attributable
229229

230230
/** Reconstructs a path that can be passed to a Series constructor */
231231
std::string filePath() const;
232+
std::string printGroup() const;
232233
};
233234

234235
/**

src/CustomHierarchy.cpp

Lines changed: 196 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
#include "openPMD/IO/IOTask.hpp"
2626
#include "openPMD/RecordComponent.hpp"
2727
#include "openPMD/Series.hpp"
28+
#include "openPMD/auxiliary/StringManip.hpp"
2829
#include "openPMD/backend/Attributable.hpp"
2930

31+
#include <algorithm>
3032
#include <deque>
3133
#include <memory>
3234

@@ -36,7 +38,13 @@ namespace internal
3638
{
3739
bool MeshesParticlesPath::ignore(const std::string &name) const
3840
{
39-
return paths.find(name) != paths.end();
41+
auto no_slashes = [](std::string const &str) {
42+
return auxiliary::trim(str, [](char const &c) { return c == '/'; });
43+
};
44+
return (meshesPath.has_value() &&
45+
name == no_slashes(meshesPath.value())) ||
46+
(particlesPath.has_value() &&
47+
name == no_slashes(particlesPath.value()));
4048
}
4149

4250
CustomHierarchyData::CustomHierarchyData()
@@ -62,16 +70,200 @@ CustomHierarchy::CustomHierarchy()
6270
CustomHierarchy::CustomHierarchy(NoInit) : Container_t(NoInit())
6371
{}
6472

73+
void CustomHierarchy::readMeshes(std::string const &meshesPath)
74+
{
75+
Parameter<Operation::OPEN_PATH> pOpen;
76+
Parameter<Operation::LIST_PATHS> pList;
77+
78+
pOpen.path = meshesPath;
79+
IOHandler()->enqueue(IOTask(&meshes, pOpen));
80+
81+
meshes.readAttributes(ReadMode::FullyReread);
82+
83+
internal::EraseStaleEntries<decltype(meshes)> map{meshes};
84+
85+
/* obtain all non-scalar meshes */
86+
IOHandler()->enqueue(IOTask(&meshes, pList));
87+
IOHandler()->flush(internal::defaultFlushParams);
88+
89+
Parameter<Operation::LIST_ATTS> aList;
90+
for (auto const &mesh_name : *pList.paths)
91+
{
92+
Mesh &m = map[mesh_name];
93+
pOpen.path = mesh_name;
94+
aList.attributes->clear();
95+
IOHandler()->enqueue(IOTask(&m, pOpen));
96+
IOHandler()->enqueue(IOTask(&m, aList));
97+
IOHandler()->flush(internal::defaultFlushParams);
98+
99+
auto att_begin = aList.attributes->begin();
100+
auto att_end = aList.attributes->end();
101+
auto value = std::find(att_begin, att_end, "value");
102+
auto shape = std::find(att_begin, att_end, "shape");
103+
if (value != att_end && shape != att_end)
104+
{
105+
MeshRecordComponent &mrc = m;
106+
IOHandler()->enqueue(IOTask(&mrc, pOpen));
107+
IOHandler()->flush(internal::defaultFlushParams);
108+
mrc.get().m_isConstant = true;
109+
}
110+
m.read();
111+
try
112+
{
113+
m.read();
114+
}
115+
catch (error::ReadError const &err)
116+
{
117+
std::cerr << "Cannot read mesh with name '" << mesh_name
118+
<< "' and will skip it due to read error:\n"
119+
<< err.what() << std::endl;
120+
map.forget(mesh_name);
121+
}
122+
}
123+
124+
/* obtain all scalar meshes */
125+
Parameter<Operation::LIST_DATASETS> dList;
126+
IOHandler()->enqueue(IOTask(&meshes, dList));
127+
IOHandler()->flush(internal::defaultFlushParams);
128+
129+
Parameter<Operation::OPEN_DATASET> dOpen;
130+
for (auto const &mesh_name : *dList.datasets)
131+
{
132+
Mesh &m = map[mesh_name];
133+
dOpen.name = mesh_name;
134+
IOHandler()->enqueue(IOTask(&m, dOpen));
135+
IOHandler()->flush(internal::defaultFlushParams);
136+
MeshRecordComponent &mrc = m;
137+
IOHandler()->enqueue(IOTask(&mrc, dOpen));
138+
IOHandler()->flush(internal::defaultFlushParams);
139+
mrc.written() = false;
140+
mrc.resetDataset(Dataset(*dOpen.dtype, *dOpen.extent));
141+
mrc.written() = true;
142+
try
143+
{
144+
m.read();
145+
}
146+
catch (error::ReadError const &err)
147+
{
148+
std::cerr << "Cannot read mesh with name '" << mesh_name
149+
<< "' and will skip it due to read error:\n"
150+
<< err.what() << std::endl;
151+
map.forget(mesh_name);
152+
}
153+
}
154+
}
155+
156+
void CustomHierarchy::readParticles(std::string const &particlesPath)
157+
{
158+
Parameter<Operation::OPEN_PATH> pOpen;
159+
Parameter<Operation::LIST_PATHS> pList;
160+
161+
pOpen.path = particlesPath;
162+
IOHandler()->enqueue(IOTask(&particles, pOpen));
163+
164+
particles.readAttributes(ReadMode::FullyReread);
165+
166+
/* obtain all particle species */
167+
pList.paths->clear();
168+
IOHandler()->enqueue(IOTask(&particles, pList));
169+
IOHandler()->flush(internal::defaultFlushParams);
170+
171+
internal::EraseStaleEntries<decltype(particles)> map{particles};
172+
for (auto const &species_name : *pList.paths)
173+
{
174+
ParticleSpecies &p = map[species_name];
175+
pOpen.path = species_name;
176+
IOHandler()->enqueue(IOTask(&p, pOpen));
177+
IOHandler()->flush(internal::defaultFlushParams);
178+
try
179+
{
180+
p.read();
181+
}
182+
catch (error::ReadError const &err)
183+
{
184+
std::cerr << "Cannot read particle species with name '"
185+
<< species_name
186+
<< "' and will skip it due to read error:\n"
187+
<< err.what() << std::endl;
188+
map.forget(species_name);
189+
}
190+
}
191+
}
192+
65193
void CustomHierarchy::read(internal::MeshesParticlesPath const &mpp)
66194
{
67195
/*
68196
* Convention for CustomHierarchy::flush and CustomHierarchy::read:
69197
* Path is created/opened already at entry point of method, method needs
70198
* to create/open path for contained subpaths.
71199
*/
72-
Attributable::readAttributes(ReadMode::FullyReread);
200+
73201
Parameter<Operation::LIST_PATHS> pList;
74202
IOHandler()->enqueue(IOTask(this, pList));
203+
IOHandler()->flush(internal::defaultFlushParams);
204+
205+
auto thisGroupHasMeshesOrParticles =
206+
[&pList](std::optional<std::string> meshesOrParticlesPath) -> bool {
207+
if (!meshesOrParticlesPath.has_value())
208+
{
209+
return false;
210+
}
211+
auto no_slashes = [](std::string const &str) {
212+
return auxiliary::trim(str, [](char const &c) { return c == '/'; });
213+
};
214+
std::string look_for = no_slashes(meshesOrParticlesPath.value());
215+
auto const &paths = *pList.paths;
216+
return std::find_if(
217+
paths.begin(),
218+
paths.end(),
219+
[&no_slashes, &look_for](std::string const &entry) {
220+
return no_slashes(entry) == look_for;
221+
}) != paths.end();
222+
};
223+
224+
if (thisGroupHasMeshesOrParticles(mpp.meshesPath))
225+
{
226+
try
227+
{
228+
readMeshes(mpp.meshesPath.value());
229+
}
230+
catch (error::ReadError const &err)
231+
{
232+
std::cerr << "Cannot read meshes at location '"
233+
<< myPath().printGroup()
234+
<< "' and will skip them due to read error:\n"
235+
<< err.what() << std::endl;
236+
meshes = {};
237+
meshes.dirty() = false;
238+
}
239+
}
240+
else
241+
{
242+
meshes.dirty() = false;
243+
}
244+
245+
if (thisGroupHasMeshesOrParticles(mpp.particlesPath))
246+
{
247+
try
248+
{
249+
readParticles(mpp.particlesPath.value());
250+
}
251+
catch (error::ReadError const &err)
252+
{
253+
std::cerr << "Cannot read particles at location '"
254+
<< myPath().printGroup()
255+
<< "' and will skip them due to read error:\n"
256+
<< err.what() << std::endl;
257+
particles = {};
258+
particles.dirty() = false;
259+
}
260+
}
261+
else
262+
{
263+
particles.dirty() = false;
264+
}
265+
266+
Attributable::readAttributes(ReadMode::FullyReread);
75267
Parameter<Operation::LIST_DATASETS> dList;
76268
IOHandler()->enqueue(IOTask(this, dList));
77269
IOHandler()->flush(internal::defaultFlushParams);
@@ -147,7 +339,7 @@ void CustomHierarchy::flush(
147339
* meshesPath and particlesPath are stored there */
148340
Series s = retrieveSeries();
149341

150-
if (!meshes.empty() || s.containsAttribute("meshesPath"))
342+
if (!meshes.empty())
151343
{
152344
if (!s.containsAttribute("meshesPath"))
153345
{
@@ -163,7 +355,7 @@ void CustomHierarchy::flush(
163355
meshes.dirty() = false;
164356
}
165357

166-
if (!particles.empty() || s.containsAttribute("particlesPath"))
358+
if (!particles.empty())
167359
{
168360
if (!s.containsAttribute("particlesPath"))
169361
{

0 commit comments

Comments
 (0)