openPMD-api
RecordComponent.hpp
1 /* Copyright 2018-2022 Axel Huebl and Franz Poeschel
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  * The function `bind_container` is based on std_bind.h in pybind11
22  * Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
23  *
24  * BSD-style license, see pybind11 LICENSE file.
25  */
26 
27 #pragma once
28 
29 #include "openPMD/RecordComponent.hpp"
30 
31 #include <pybind11/numpy.h>
32 #include <pybind11/pybind11.h>
33 #include <pybind11/stl.h>
34 
35 #include <utility>
36 
37 namespace py = pybind11;
38 using namespace openPMD;
39 
40 /*
41  * Definitions for these functions `load_chunk` and `store_chunk` found in
42  * python/RecordComponent.cpp.
43  * No need to pull them here, as they are not templates.
44  */
45 py::array load_chunk(RecordComponent &r, py::tuple const &slices);
46 
47 void store_chunk(RecordComponent &r, py::array &a, py::tuple const &slices);
48 
49 namespace docstring
50 {
51 constexpr static char const *is_scalar = R"docstr(
52 Returns true if this record only contains a single component.
53 )docstr";
54 }
55 
56 template <typename Class>
57 Class &&addRecordComponentSetGet(Class &&class_)
58 {
59  // TODO if we also want to support scalar arrays, we have to switch
60  // py::array for py::buffer as in Attributable
61  // https://github.com/pybind/pybind11/pull/1537
62 
63  // slicing protocol
64  class_
65  .def(
66  "__getitem__",
67  [](RecordComponent &r, py::tuple const &slices) {
68  return load_chunk(r, slices);
69  },
70  py::arg("tuple of index slices"))
71  .def(
72  "__getitem__",
73  [](RecordComponent &r, py::slice const &slice_obj) {
74  auto const slices = py::make_tuple(slice_obj);
75  return load_chunk(r, slices);
76  },
77  py::arg("slice"))
78  .def(
79  "__getitem__",
80  [](RecordComponent &r, py::int_ const &slice_obj) {
81  auto const slices = py::make_tuple(slice_obj);
82  return load_chunk(r, slices);
83  },
84  py::arg("axis index"))
85 
86  .def(
87  "__setitem__",
88  [](RecordComponent &r, py::tuple const &slices, py::array &a) {
89  store_chunk(r, a, slices);
90  },
91  py::arg("tuple of index slices"),
92  py::arg("array with values to assign"))
93  .def(
94  "__setitem__",
95  [](RecordComponent &r, py::slice const &slice_obj, py::array &a) {
96  auto const slices = py::make_tuple(slice_obj);
97  store_chunk(r, a, slices);
98  },
99  py::arg("slice"),
100  py::arg("array with values to assign"))
101  .def(
102  "__setitem__",
103  [](RecordComponent &r, py::int_ const &slice_obj, py::array &a) {
104  auto const slices = py::make_tuple(slice_obj);
105  store_chunk(r, a, slices);
106  },
107  py::arg("axis index"),
108  py::arg("array with values to assign"));
109  return std::forward<Class>(class_);
110 }
Definition: RecordComponent.hpp:120
Public definitions of openPMD-api.
Definition: Date.cpp:29