Skip to content

Commit ae9c9a1

Browse files
committed
Same trick for Dataset() constructor
1 parent 642e1f4 commit ae9c9a1

8 files changed

Lines changed: 88 additions & 30 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ endif()
550550
if(openPMD_HAVE_PYTHON)
551551
add_library(openPMD.py MODULE
552552
src/binding/python/openPMD.cpp
553+
src/binding/python/auxiliary.cpp
553554
src/binding/python/Access.cpp
554555
src/binding/python/Attributable.cpp
555556
src/binding/python/BaseRecordComponent.cpp

examples/13_write_dynamic_configuration.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#!/usr/bin/env python
2-
import json
3-
42
import numpy as np
53
import openpmd_api as io
64

@@ -20,7 +18,8 @@
2018
# be passed by adding an at-sign `@` in front of the path
2119
# The format will then be recognized by filename extension, i.e. .json or .toml
2220
# In Python, normal Python dictionaries can also be used which will then be
23-
# converted via `json.dumps()` in the Series constructor.
21+
# converted via `json.dumps()` in the Series constructor
22+
# (see below for an example in terms of the Dataset constructor)
2423
2524
backend = "adios2"
2625
iteration_encoding = "group_based"
@@ -107,9 +106,6 @@ def main():
107106
'dataset': {
108107
'operators': []
109108
}
110-
},
111-
'adios1': {
112-
'dataset': {}
113109
}
114110
}
115111
config['adios2']['dataset'] = {
@@ -120,9 +116,6 @@ def main():
120116
}
121117
}]
122118
}
123-
config['adios1']['dataset'] = {
124-
'transform': 'blosc:compressor=zlib,shuffle=bit,lvl=1;nometa'
125-
}
126119

127120
temperature = iteration.meshes["temperature"]
128121
temperature.unit_dimension = {io.Unit_Dimension.theta: 1.0}
@@ -131,8 +124,7 @@ def main():
131124
# temperature has no x,y,z components, so skip the last layer:
132125
temperature_dataset = temperature
133126
# let's say we are in a 3x3 mesh
134-
dataset = io.Dataset(np.dtype("double"), [3, 3])
135-
dataset.options = json.dumps(config)
127+
dataset = io.Dataset(np.dtype("double"), [3, 3], config)
136128
temperature_dataset.reset_dataset(dataset)
137129
# temperature is constant
138130
local_data = np.arange(i * 9, (i + 1) * 9, dtype=np.dtype("double"))

examples/7_extended_write_serial.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
Authors: Axel Huebl, Fabian Koller
77
License: LGPLv3+
88
"""
9-
import json
10-
119
import numpy as np
1210
from openpmd_api import (Access, Dataset, Mesh_Record_Component, Series,
1311
Unit_Dimension)
@@ -104,7 +102,6 @@
104102
# before storing record data, you must specify the dataset once per
105103
# component this describes the datatype and shape of data as it should be
106104
# written to disk
107-
d = Dataset(partial_mesh.dtype, extent=[2, 5])
108105
dataset_config = {
109106
"adios2": {
110107
"dataset": {
@@ -117,7 +114,7 @@
117114
}
118115
}
119116
}
120-
d.options = json.dumps(dataset_config)
117+
d = Dataset(partial_mesh.dtype, extent=[2, 5], options=dataset_config)
121118
mesh["x"].reset_dataset(d)
122119

123120
electrons = cur_it.particles["electrons"]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* Copyright 2025 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+
22+
#pragma once
23+
24+
#include "openPMD/binding/python/Common.hpp"
25+
26+
namespace auxiliary
27+
{
28+
auto json_dumps(py::object const &obj) -> std::string;
29+
}

src/binding/python/Dataset.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,43 @@
2222

2323
#include "openPMD/binding/python/Common.hpp"
2424
#include "openPMD/binding/python/Numpy.hpp"
25+
#include "openPMD/binding/python/auxiliary.hpp"
2526

2627
#include <string>
2728

2829
void init_Dataset(py::module &m)
2930
{
3031
auto pyDataset =
3132
py::class_<Dataset>(m, "Dataset")
33+
.def(py::init<Extent>(), py::arg("extent"))
3234
.def(
33-
py::init<Datatype, Extent>(),
35+
py::init<Datatype, Extent, std::string>(),
3436
py::arg("dtype"),
35-
py::arg("extent"))
36-
.def(py::init<Extent>(), py::arg("extent"))
37+
py::arg("extent"),
38+
py::arg("options") = "{}")
3739
.def(
38-
py::init([](py::dtype dt, Extent const &e) {
40+
py::init([](py::dtype dt, Extent e, std::string options) {
3941
auto const d = dtype_from_numpy(std::move(dt));
40-
return new Dataset{d, e};
42+
return new Dataset{d, std::move(e), std::move(options)};
4143
}),
4244
py::arg("dtype"),
43-
py::arg("extent"))
45+
py::arg("extent"),
46+
py::arg("options") = "{}")
4447
.def(
45-
py::init<Datatype, Extent, std::string>(),
48+
py::init([](Datatype dt, Extent e, py::object const &options) {
49+
auto resolved_options = ::auxiliary::json_dumps(options);
50+
return new Dataset{
51+
dt, std::move(e), std::move(resolved_options)};
52+
}),
4653
py::arg("dtype"),
4754
py::arg("extent"),
4855
py::arg("options"))
4956
.def(
50-
py::init([](py::dtype dt, Extent e, std::string options) {
57+
py::init([](py::dtype dt, Extent e, py::object const &options) {
5158
auto const d = dtype_from_numpy(std::move(dt));
52-
return new Dataset{d, std::move(e), std::move(options)};
59+
auto resolved_options = ::auxiliary::json_dumps(options);
60+
return new Dataset{
61+
d, std::move(e), std::move(resolved_options)};
5362
}),
5463
py::arg("dtype"),
5564
py::arg("extent"),

src/binding/python/Series.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
// re-implemented signatures:
3838
// include <mpi4py/mpi4py.h>
3939
#include "openPMD/binding/python/Mpi.hpp"
40+
#include "openPMD/binding/python/auxiliary.hpp"
4041
#include <mpi.h>
4142
#endif
4243

@@ -81,10 +82,7 @@ struct DefineSeriesConstructorPerPathType
8182

8283
static auto json_cfg_as_string(py::object const &obj) -> std::string
8384
{
84-
py::module_ json = py::module_::import("json");
85-
auto dumps = json.attr("dumps");
86-
auto dumped = dumps(obj);
87-
return py::cast<std::string>(dumped);
85+
return ::auxiliary::json_dumps(obj);
8886
}
8987

9088
template <typename TupleType>

src/binding/python/auxiliary.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* Copyright 2025 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+
22+
#include "openPMD/binding/python/auxiliary.hpp"
23+
24+
namespace auxiliary
25+
{
26+
auto json_dumps(py::object const &obj) -> std::string
27+
{
28+
py::module_ json = py::module_::import("json");
29+
auto dumps = json.attr("dumps");
30+
auto dumped = dumps(obj);
31+
return py::cast<std::string>(dumped);
32+
}
33+
} // namespace auxiliary

test/python/unittest/API/APITest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,8 +2129,7 @@ def testJsonConfigADIOS2(self):
21292129
E_x.store_chunk(data, [0], [1000])
21302130

21312131
E_y = series.iterations[0].meshes["E"]["y"]
2132-
import json
2133-
E_y.reset_dataset(DS(np.dtype("double"), [1000], json.dumps(local_config)))
2132+
E_y.reset_dataset(DS(np.dtype("double"), [1000], local_config))
21342133
E_y.store_chunk(data, [0], [1000])
21352134

21362135
self.assertTrue(series)

0 commit comments

Comments
 (0)