openPMD-api
Iteration.hpp
1 /* Copyright 2017-2021 Fabian Koller
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include "openPMD/IterationEncoding.hpp"
24 #include "openPMD/Mesh.hpp"
25 #include "openPMD/ParticleSpecies.hpp"
26 #include "openPMD/Streaming.hpp"
27 #include "openPMD/auxiliary/Variant.hpp"
28 #include "openPMD/backend/Attributable.hpp"
29 #include "openPMD/backend/Container.hpp"
30 
31 #include <cstdint>
32 #include <deque>
33 #include <optional>
34 #include <set>
35 #include <tuple>
36 
37 namespace openPMD
38 {
39 namespace internal
40 {
45  enum class CloseStatus
46  {
48  Open,
55  };
56 
58  {
64  std::string path;
68  uint64_t iteration = 0;
73  bool fileBased = false;
78  std::string filename;
79  bool beginStep = false;
80  };
81 
83  {
84  public:
85  /*
86  * An iteration may be logically closed in the frontend,
87  * but not necessarily yet in the backend.
88  * Will be propagated to the backend upon next flush.
89  * Store the current status.
90  * Once an iteration has been closed, no further flushes shall be
91  * performed. If flushing a closed file, the old file may otherwise be
92  * overwritten.
93  */
94  CloseStatus m_closed = CloseStatus::Open;
95 
103  StepStatus m_stepStatus = StepStatus::NoStep;
104 
109  std::optional<DeferredParseAccess> m_deferredParseAccess{};
110 
117  std::optional<std::string> m_overrideFilebasedFilename{};
118  };
119 } // namespace internal
126 class Iteration : public Attributable
127 {
128  template <typename T, typename T_key, typename T_container>
129  friend class Container;
130  friend class Series;
131  friend class WriteIterations;
132  friend class SeriesIterator;
133 
134 public:
135  Iteration(Iteration const &) = default;
136  Iteration &operator=(Iteration const &) = default;
137 
138  using IterationIndex_t = uint64_t;
139 
145  template <typename T>
146  T time() const;
154  template <typename T>
155  Iteration &setTime(T newTime);
156 
162  template <typename T>
163  T dt() const;
171  template <typename T>
172  Iteration &setDt(T newDt);
173 
177  double timeUnitSI() const;
183  Iteration &setTimeUnitSI(double newTimeUnitSI);
184 
194  /*
195  * Note: If the API is changed in future to allow reopening closed
196  * iterations, measures should be taken to prevent this in the streaming
197  * API. Currently, disallowing to reopen closed iterations satisfies
198  * the requirements of the streaming API.
199  */
200  Iteration &close(bool flush = true);
201 
215  Iteration &open();
216 
223  bool closed() const;
224 
236  [[deprecated("This attribute is no longer set by the openPMD-api.")]] bool
237  closedByWriter() const;
238 
239  Container<Mesh> meshes{};
240  Container<ParticleSpecies> particles{}; // particleSpecies?
241 
242  virtual ~Iteration() = default;
243 
244 private:
245  Iteration();
246 
247  std::shared_ptr<internal::IterationData> m_iterationData{
249 
250  inline internal::IterationData const &get() const
251  {
252  return *m_iterationData;
253  }
254 
255  inline internal::IterationData &get()
256  {
257  return *m_iterationData;
258  }
259 
260  void flushFileBased(
261  std::string const &, IterationIndex_t, internal::FlushParams const &);
262  void flushGroupBased(IterationIndex_t, internal::FlushParams const &);
263  void flushVariableBased(IterationIndex_t, internal::FlushParams const &);
264  void flush(internal::FlushParams const &);
265  void deferParseAccess(internal::DeferredParseAccess);
266  /*
267  * Control flow for runDeferredParseAccess(), readFileBased(),
268  * readGroupBased() and read_impl():
269  * runDeferredParseAccess() is called as the entry point.
270  * File-based and group-based
271  * iteration layouts need to be parsed slightly differently:
272  * In file-based iteration layout, each iteration's file also contains
273  * attributes for the /data group. In group-based layout, those have
274  * already been parsed during opening of the Series.
275  * Hence, runDeferredParseAccess() will call either readFileBased() or
276  * readGroupBased() to
277  * allow for those different control flows.
278  * Finally, read_impl() is called which contains the common parsing
279  * logic for an iteration.
280  *
281  * reread() reads again an Iteration that has been previously read.
282  * Calling it on an Iteration not yet parsed is an error.
283  *
284  */
285  void reread(std::string const &path);
286  void readFileBased(
287  std::string filePath, std::string const &groupPath, bool beginStep);
288  void readGorVBased(std::string const &groupPath, bool beginStep);
289  void read_impl(std::string const &groupPath);
290  void readMeshes(std::string const &meshesPath);
291  void readParticles(std::string const &particlesPath);
292 
298  struct BeginStepStatus
299  {
300  using AvailableIterations_t = std::optional<std::deque<uint64_t> >;
301 
302  AdvanceStatus stepStatus{};
303  /*
304  * If the iteration attribute `snapshot` is present, the value of that
305  * attribute. Otherwise empty.
306  */
307  AvailableIterations_t iterationsInOpenedStep;
308 
309  /*
310  * Most of the time, the AdvanceStatus part of this struct is what we
311  * need, so let's make it easy to access.
312  */
313  inline operator AdvanceStatus() const
314  {
315  return stepStatus;
316  }
317 
318  /*
319  * Support for std::tie()
320  */
321  inline operator std::tuple<AdvanceStatus &, AvailableIterations_t &>()
322  {
323  return std::tuple<AdvanceStatus &, AvailableIterations_t &>{
324  stepStatus, iterationsInOpenedStep};
325  }
326  };
327 
335  BeginStepStatus beginStep(bool reread);
336 
337  /*
338  * Iteration-independent variant for beginStep().
339  * Useful in group-based iteration encoding where the Iteration will only
340  * be known after opening the step.
341  */
342  static BeginStepStatus beginStep(
343  std::optional<Iteration> thisObject,
344  Series &series,
345  bool reread,
346  std::set<IterationIndex_t> const &ignoreIterations = {});
347 
353  void endStep();
354 
363  StepStatus getStepStatus();
364 
373  void setStepStatus(StepStatus);
374 
375  /*
376  * @brief Check recursively whether this Iteration is dirty.
377  * It is dirty if any attribute or dataset is read from or written to
378  * the backend.
379  *
380  * @return true If dirty.
381  * @return false Otherwise.
382  */
383  bool dirtyRecursive() const;
384 
390  virtual void linkHierarchy(Writable &w);
391 
397  void runDeferredParseAccess();
398 }; // Iteration
399 
400 extern template float Iteration::time<float>() const;
401 
402 extern template double Iteration::time<double>() const;
403 
404 extern template long double Iteration::time<long double>() const;
405 
406 template <typename T>
407 inline T Iteration::time() const
408 {
409  return this->readFloatingpoint<T>("time");
410 }
411 
412 extern template float Iteration::dt<float>() const;
413 
414 extern template double Iteration::dt<double>() const;
415 
416 extern template long double Iteration::dt<long double>() const;
417 
418 template <typename T>
419 inline T Iteration::dt() const
420 {
421  return this->readFloatingpoint<T>("dt");
422 }
423 } // namespace openPMD
T time() const
Definition: Iteration.hpp:407
The reader has not yet parsed this iteration.
std::string filename
If fileBased == true, the file name (without file path) of the file containing this iteration...
Definition: Iteration.hpp:78
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:126
Definition: Iteration.hpp:57
StepStatus
Used in step-based mode (i.e.
Definition: Streaming.hpp:45
T dt() const
Definition: Iteration.hpp:419
AdvanceStatus
In step-based mode (i.e.
Definition: Streaming.hpp:20
Definition: WriteIterations.hpp:53
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:186
Iteration has not been closed.
Public definitions of openPMD-api.
Layer to mirror structure of logical data and persistent data in file.
Definition: Writable.hpp:64
Definition: Attributable.hpp:56
Definition: ReadIterations.hpp:54
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition: AbstractIOHandler.hpp:84
Definition: Iteration.hpp:82
CloseStatus
Whether an iteration has been closed yet.
Definition: Iteration.hpp:45
std::string path
The group path within /data containing this iteration.
Definition: Iteration.hpp:64
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:131
Layer to manage storage of attributes associated with file objects.
Definition: Attributable.hpp:93