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/Option.hpp"
28 #include "openPMD/auxiliary/Variant.hpp"
29 #include "openPMD/backend/Attributable.hpp"
30 #include "openPMD/backend/Container.hpp"
31 
32 namespace openPMD
33 {
41 {
42  template <typename T, typename T_key, typename T_container>
43  friend class Container;
44  friend class SeriesInterface;
45  friend class WriteIterations;
46  friend class SeriesIterator;
47 
48 public:
49  Iteration(Iteration const &) = default;
50  Iteration &operator=(Iteration const &) = default;
51 
57  template <typename T>
58  T time() const;
66  template <typename T>
67  Iteration &setTime(T newTime);
68 
74  template <typename T>
75  T dt() const;
83  template <typename T>
84  Iteration &setDt(T newDt);
85 
89  double timeUnitSI() const;
95  Iteration &setTimeUnitSI(double newTimeUnitSI);
96 
106  /*
107  * Note: If the API is changed in future to allow reopening closed
108  * iterations, measures should be taken to prevent this in the streaming
109  * API. Currently, disallowing to reopen closed iterations satisfies
110  * the requirements of the streaming API.
111  */
112  Iteration &close(bool flush = true);
113 
127  Iteration &open();
128 
135  bool closed() const;
136 
148  bool closedByWriter() const;
149 
150  Container<Mesh> meshes;
151  Container<ParticleSpecies> particles; // particleSpecies?
152 
153  virtual ~Iteration() = default;
154 
155 private:
156  Iteration();
157 
158  struct DeferredParseAccess
159  {
165  std::string path;
169  uint64_t iteration = 0;
174  bool fileBased = false;
179  std::string filename;
180  bool beginStep = false;
181  };
182 
183  void flushFileBased(
184  std::string const &, uint64_t, internal::FlushParams const &);
185  void flushGroupBased(uint64_t, internal::FlushParams const &);
186  void flushVariableBased(uint64_t, internal::FlushParams const &);
187  void flush(internal::FlushParams const &);
188  void deferParseAccess(DeferredParseAccess);
189  /*
190  * Control flow for runDeferredParseAccess(), readFileBased(),
191  * readGroupBased() and read_impl():
192  * runDeferredParseAccess() is called as the entry point.
193  * File-based and group-based
194  * iteration layouts need to be parsed slightly differently:
195  * In file-based iteration layout, each iteration's file also contains
196  * attributes for the /data group. In group-based layout, those have
197  * already been parsed during opening of the Series.
198  * Hence, runDeferredParseAccess() will call either readFileBased() or
199  * readGroupBased() to
200  * allow for those different control flows.
201  * Finally, read_impl() is called which contains the common parsing
202  * logic for an iteration.
203  *
204  * reread() reads again an Iteration that has been previously read.
205  * Calling it on an Iteration not yet parsed is an error.
206  *
207  */
208  void reread(std::string const &path);
209  void readFileBased(
210  std::string filePath, std::string const &groupPath, bool beginStep);
211  void readGorVBased(std::string const &groupPath, bool beginStep);
212  void read_impl(std::string const &groupPath);
213 
218  enum class CloseStatus
219  {
220  ParseAccessDeferred,
221  Open,
222  ClosedInFrontend,
224  ClosedInBackend,
226  ClosedTemporarily
228  };
229 
230  /*
231  * An iteration may be logically closed in the frontend,
232  * but not necessarily yet in the backend.
233  * Will be propagated to the backend upon next flush.
234  * Store the current status.
235  * Once an iteration has been closed, no further flushes shall be performed.
236  * If flushing a closed file, the old file may otherwise be overwritten.
237  */
238  std::shared_ptr<CloseStatus> m_closed =
239  std::make_shared<CloseStatus>(CloseStatus::Open);
240 
248  std::shared_ptr<StepStatus> m_stepStatus =
249  std::make_shared<StepStatus>(StepStatus::NoStep);
250 
251  std::shared_ptr<auxiliary::Option<DeferredParseAccess> >
252  m_deferredParseAccess =
253  std::make_shared<auxiliary::Option<DeferredParseAccess> >(
255 
256  std::shared_ptr<auxiliary::Option<std::string> >
257  m_overrideFilebasedFilename =
258  std::make_shared<auxiliary::Option<std::string> >(
260 
268  AdvanceStatus beginStep(bool reread);
269 
277  void endStep();
278 
287  StepStatus getStepStatus();
288 
297  void setStepStatus(StepStatus);
298 
299  /*
300  * @brief Check recursively whether this Iteration is dirty.
301  * It is dirty if any attribute or dataset is read from or written to
302  * the backend.
303  *
304  * @return true If dirty.
305  * @return false Otherwise.
306  */
307  bool dirtyRecursive() const;
308 
314  virtual void linkHierarchy(Writable &w);
315 
321  void runDeferredParseAccess();
322 }; // Iteration
323 
324 extern template float Iteration::time<float>() const;
325 
326 extern template double Iteration::time<double>() const;
327 
328 extern template long double Iteration::time<long double>() const;
329 
330 template <typename T>
331 inline T Iteration::time() const
332 {
333  return this->readFloatingpoint<T>("time");
334 }
335 
336 extern template float Iteration::dt<float>() const;
337 
338 extern template double Iteration::dt<double>() const;
339 
340 extern template long double Iteration::dt<long double>() const;
341 
342 template <typename T>
343 inline T Iteration::dt() const
344 {
345  return this->readFloatingpoint<T>("dt");
346 }
347 } // namespace openPMD
T time() const
Definition: Iteration.hpp:331
Iteration & setDt(T newDt)
Set the time step used to reach this iteration.
Definition: Iteration.cpp:57
double timeUnitSI() const
Definition: Iteration.cpp:67
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:40
Iteration & open()
Open an iteration.
Definition: Iteration.cpp:146
StepStatus
Used in step-based mode (i.e.
Definition: Streaming.hpp:44
T dt() const
Definition: Iteration.hpp:343
Iteration & close(bool flush=true)
Close an iteration.
Definition: Iteration.cpp:80
AdvanceStatus
In step-based mode (i.e.
Definition: Streaming.hpp:20
Writing side of the streaming API.
Definition: WriteIterations.hpp:46
bool closed() const
Has the iteration been closed? A closed iteration may not (yet) be reopened.
Definition: Iteration.cpp:161
Simple Option type based on variantSrc::variant.
Definition: Option.hpp:45
Public definitions of openPMD-api.
Definition: Date.cpp:28
Layer to mirror structure of logical data and persistent data in file.
Definition: Writable.hpp:63
Definition: ReadIterations.hpp:48
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition: AbstractIOHandler.hpp:103
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:110
Iteration & setTime(T newTime)
Set the global reference time for this iteration.
Definition: Iteration.cpp:46
bool closedByWriter() const
Has the iteration been closed by the writer? Background: Upon calling Iteration::close(), the openPMD API will add metadata to the iteration in form of an attribute, indicating that the iteration has indeed been closed.
Definition: Iteration.cpp:181
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:105
Iteration & setTimeUnitSI(double newTimeUnitSI)
Set the conversion factor to convert time and dt to seconds.
Definition: Iteration.cpp:72
Definition: Attributable.hpp:444