py-pluto 1.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyPLUTO/__init__.py +22 -0
- pyPLUTO/amr.py +745 -0
- pyPLUTO/baseloadmixin.py +258 -0
- pyPLUTO/baseloadstate.py +45 -0
- pyPLUTO/codes/echo_load.py +161 -0
- pyPLUTO/configure.py +261 -0
- pyPLUTO/gui/config.py +174 -0
- pyPLUTO/gui/custom_var.py +435 -0
- pyPLUTO/gui/globals.py +108 -0
- pyPLUTO/gui/main.py +17 -0
- pyPLUTO/gui/main_window.py +177 -0
- pyPLUTO/gui/panels.py +66 -0
- pyPLUTO/gui/utils.py +273 -0
- pyPLUTO/h_pypluto.py +84 -0
- pyPLUTO/image.py +302 -0
- pyPLUTO/imagefuncs/colorbar.py +240 -0
- pyPLUTO/imagefuncs/contour.py +254 -0
- pyPLUTO/imagefuncs/create_axes.py +464 -0
- pyPLUTO/imagefuncs/display.py +306 -0
- pyPLUTO/imagefuncs/figure.py +395 -0
- pyPLUTO/imagefuncs/imagetools.py +487 -0
- pyPLUTO/imagefuncs/interactive.py +403 -0
- pyPLUTO/imagefuncs/legend.py +250 -0
- pyPLUTO/imagefuncs/plot.py +311 -0
- pyPLUTO/imagefuncs/range.py +242 -0
- pyPLUTO/imagefuncs/scatter.py +270 -0
- pyPLUTO/imagefuncs/set_axis.py +497 -0
- pyPLUTO/imagefuncs/streamplot.py +297 -0
- pyPLUTO/imagefuncs/zoom.py +428 -0
- pyPLUTO/imagemixin.py +259 -0
- pyPLUTO/imagestate.py +45 -0
- pyPLUTO/load.py +447 -0
- pyPLUTO/loadfuncs/baseloadtools.py +71 -0
- pyPLUTO/loadfuncs/codeselection.py +48 -0
- pyPLUTO/loadfuncs/defpluto.py +123 -0
- pyPLUTO/loadfuncs/descriptor.py +102 -0
- pyPLUTO/loadfuncs/findfiles.py +182 -0
- pyPLUTO/loadfuncs/findformat.py +245 -0
- pyPLUTO/loadfuncs/initload.py +203 -0
- pyPLUTO/loadfuncs/loadvars.py +227 -0
- pyPLUTO/loadfuncs/offsetdata.py +87 -0
- pyPLUTO/loadfuncs/offsetfluid.py +408 -0
- pyPLUTO/loadfuncs/read_files.py +213 -0
- pyPLUTO/loadfuncs/readdata.py +619 -0
- pyPLUTO/loadfuncs/readdata_old.py +567 -0
- pyPLUTO/loadfuncs/readdefplini.py +101 -0
- pyPLUTO/loadfuncs/readfluid.py +479 -0
- pyPLUTO/loadfuncs/readformat.py +277 -0
- pyPLUTO/loadfuncs/readgridalone.py +224 -0
- pyPLUTO/loadfuncs/readgridfile.py +255 -0
- pyPLUTO/loadfuncs/readgridout.py +451 -0
- pyPLUTO/loadfuncs/readpart.py +419 -0
- pyPLUTO/loadfuncs/readtab.py +105 -0
- pyPLUTO/loadfuncs/write_files.py +283 -0
- pyPLUTO/loadmixin.py +419 -0
- pyPLUTO/loadpart.py +233 -0
- pyPLUTO/loadstate.py +68 -0
- pyPLUTO/newload.py +81 -0
- pyPLUTO/pytools.py +145 -0
- pyPLUTO/toolfuncs/findlines.py +551 -0
- pyPLUTO/toolfuncs/fourier.py +149 -0
- pyPLUTO/toolfuncs/nabla.py +676 -0
- pyPLUTO/toolfuncs/parttools.py +152 -0
- pyPLUTO/toolfuncs/transform.py +638 -0
- pyPLUTO/utils/annotator.py +27 -0
- pyPLUTO/utils/inspector.py +145 -0
- pyPLUTO/utils/make_docstrings.py +3 -0
- py_pluto-1.1.4.dist-info/METADATA +218 -0
- py_pluto-1.1.4.dist-info/RECORD +73 -0
- py_pluto-1.1.4.dist-info/WHEEL +5 -0
- py_pluto-1.1.4.dist-info/entry_points.txt +2 -0
- py_pluto-1.1.4.dist-info/licenses/LICENSE +27 -0
- py_pluto-1.1.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"""Docstring for pyPLUTO.loadfuncs.offsetfluid module."""
|
|
2
|
+
|
|
3
|
+
import mmap
|
|
4
|
+
import struct
|
|
5
|
+
import warnings
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import h5py
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from pyPLUTO.loadfuncs.readgridalone import GridManager
|
|
12
|
+
from pyPLUTO.loadmixin import LoadMixin
|
|
13
|
+
from pyPLUTO.loadstate import LoadState
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OffsetFluid(LoadMixin):
|
|
17
|
+
"""Class that computes the fluid offsets in single_file format."""
|
|
18
|
+
|
|
19
|
+
from pyPLUTO.amr import _DataScanHDF5, _inspect_hdf5, _read_gridfile
|
|
20
|
+
from pyPLUTO.loadfuncs.readgridout import _split_gridfile
|
|
21
|
+
from pyPLUTO.toolfuncs.transform import _congrid
|
|
22
|
+
|
|
23
|
+
def __init__(self, state: LoadState) -> None:
|
|
24
|
+
self.state = state
|
|
25
|
+
self.varoffset, self.varshape = ({}, {})
|
|
26
|
+
self.GridAloneManager = GridManager(state)
|
|
27
|
+
|
|
28
|
+
def offset_bin(
|
|
29
|
+
self, _i: int, var: str | None, exout: int, _mm: mmap.mmap
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Compute the offset and shape of the variables to be loaded.
|
|
32
|
+
|
|
33
|
+
The routine, knowing the grid shape, computes the offset and stores the
|
|
34
|
+
shape dependng on wether the variable is staggered or not.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
- None
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
- i (not optional): int
|
|
43
|
+
The index of the file to be loaded.
|
|
44
|
+
- var (not optional): str
|
|
45
|
+
The variable to be loaded.
|
|
46
|
+
|
|
47
|
+
----
|
|
48
|
+
|
|
49
|
+
Examples
|
|
50
|
+
--------
|
|
51
|
+
- Example #1: Load all the variables
|
|
52
|
+
|
|
53
|
+
>>> _offset_bin(0, True)
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
off_start = 0
|
|
57
|
+
|
|
58
|
+
grid_sizes: dict[str, tuple[int | tuple[int, ...] | None, int]] = {
|
|
59
|
+
"Bx1s": (self.nshp_st1, self.gridsize_st1),
|
|
60
|
+
"Ex1s": (self.nshp_st1, self.gridsize_st1),
|
|
61
|
+
"Bx2s": (self.nshp_st2, self.gridsize_st2),
|
|
62
|
+
"Ex2s": (self.nshp_st2, self.gridsize_st2),
|
|
63
|
+
"Bx3s": (self.nshp_st3, self.gridsize_st3),
|
|
64
|
+
"Ex3s": (self.nshp_st3, self.gridsize_st3),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Loop over the variables to be loaded (None for single files)
|
|
68
|
+
varloop = self.d_info["varslist"][exout] if var is None else [var]
|
|
69
|
+
|
|
70
|
+
for eachvar in varloop:
|
|
71
|
+
# Get the grid shape and size (centered or staggered)
|
|
72
|
+
grid_size = grid_sizes.get(eachvar, [self.nshp, self.gridsize])
|
|
73
|
+
self.varshape[eachvar] = grid_size[0]
|
|
74
|
+
# Assign the offset
|
|
75
|
+
self.varoffset[eachvar] = off_start
|
|
76
|
+
# Move to next variable
|
|
77
|
+
if isinstance(grid_size[1], int):
|
|
78
|
+
off_start += grid_size[1] * self.charsize
|
|
79
|
+
else:
|
|
80
|
+
raise ValueError("Grid size must be an integer.")
|
|
81
|
+
|
|
82
|
+
# End of function
|
|
83
|
+
|
|
84
|
+
def offset_h5(
|
|
85
|
+
self, i: int, _var: str | None, exout: int, _mm: mmap.mmap
|
|
86
|
+
) -> None:
|
|
87
|
+
"""Compute the offset and shape of the variable in hdf5 format.
|
|
88
|
+
|
|
89
|
+
The routine, knowing the grid shape, computes the offset and stores the
|
|
90
|
+
shape dependng on wether the variable is staggered or not.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
- None
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
- i (not optional): int
|
|
99
|
+
The index of the file to be loaded.
|
|
100
|
+
- var (not optional): str
|
|
101
|
+
The variable to be loaded.
|
|
102
|
+
|
|
103
|
+
----
|
|
104
|
+
|
|
105
|
+
Examples
|
|
106
|
+
--------
|
|
107
|
+
- Example #1: Load all the variables
|
|
108
|
+
|
|
109
|
+
>>> _offset_h5(0, True)
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
# Open the file with the h5py library
|
|
113
|
+
h5file = h5py.File(str(self.filepath), "r")
|
|
114
|
+
|
|
115
|
+
# Selects the binformat
|
|
116
|
+
self.d_info["binformat"][exout] = (
|
|
117
|
+
"d" if self.format == "dbl.h5" else "f"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Safely access the timestep group and its sub-items to avoid
|
|
121
|
+
# treating an h5py.Datatype as a subscriptable object.
|
|
122
|
+
timestep_key = f"Timestep_{exout}"
|
|
123
|
+
timestep = h5file.get(timestep_key, None)
|
|
124
|
+
|
|
125
|
+
if isinstance(timestep, h5py.Group):
|
|
126
|
+
timeattr = timestep.attrs["Time"]
|
|
127
|
+
idx = np.searchsorted(self.outlist, exout)
|
|
128
|
+
self.timelist[idx] = float(timeattr)
|
|
129
|
+
idx = np.searchsorted(self.noutlist, exout)
|
|
130
|
+
self.ntimelist[idx] = float(timeattr)
|
|
131
|
+
cellvs = timestep.get("vars", {})
|
|
132
|
+
stagvs = timestep.get("stag_vars", {})
|
|
133
|
+
cellvs = (
|
|
134
|
+
{}
|
|
135
|
+
if cellvs is None or isinstance(cellvs, h5py.Datatype)
|
|
136
|
+
else cellvs
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
stagvs = (
|
|
140
|
+
{}
|
|
141
|
+
if stagvs is None or isinstance(stagvs, h5py.Datatype)
|
|
142
|
+
else stagvs
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
# Timestep group not present or not a group; treat as empty
|
|
146
|
+
cellvs = {}
|
|
147
|
+
stagvs = {}
|
|
148
|
+
|
|
149
|
+
# If standalone file, finds the variables to be loaded, else
|
|
150
|
+
# remove variables in the .out file that are not present in the actual
|
|
151
|
+
# file
|
|
152
|
+
if (
|
|
153
|
+
self.alone is True
|
|
154
|
+
and isinstance(cellvs, h5py.Group | dict)
|
|
155
|
+
and isinstance(stagvs, h5py.Group | dict)
|
|
156
|
+
):
|
|
157
|
+
self.d_info["varslist"][exout] = set(cellvs.keys()) | set(
|
|
158
|
+
stagvs.keys()
|
|
159
|
+
)
|
|
160
|
+
elif not isinstance(cellvs, h5py.Group | dict) or not isinstance(
|
|
161
|
+
stagvs, h5py.Group | dict
|
|
162
|
+
):
|
|
163
|
+
raise ValueError(
|
|
164
|
+
"Error: Variables group not found in the HDF5 file."
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Loop over the variables and store the offset and shape
|
|
168
|
+
for j in self.d_info["varslist"][exout]:
|
|
169
|
+
if j in cellvs:
|
|
170
|
+
obj = cellvs[j]
|
|
171
|
+
elif j in stagvs:
|
|
172
|
+
obj = stagvs[j]
|
|
173
|
+
else:
|
|
174
|
+
obj = None
|
|
175
|
+
warnings.warn(
|
|
176
|
+
f"Warning: Variable {j} not found in the HDF5 file.",
|
|
177
|
+
UserWarning,
|
|
178
|
+
stacklevel=2,
|
|
179
|
+
)
|
|
180
|
+
# Only Dataset objects provide shape and a file offset
|
|
181
|
+
if isinstance(obj, h5py.Dataset):
|
|
182
|
+
self.varoffset[j] = obj.id.get_offset()
|
|
183
|
+
self.varshape[j] = obj.shape
|
|
184
|
+
elif obj is not None:
|
|
185
|
+
raise ValueError(
|
|
186
|
+
f"Error: Variable {j} in the HDF5 file is not a dataset."
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if self.alone is True and self.infogrid is True:
|
|
190
|
+
self.x1 = h5file["cell_coords"]["X"][:].T
|
|
191
|
+
self.x2 = h5file["cell_coords"]["Y"][:].T
|
|
192
|
+
self.x3 = h5file["cell_coords"]["Z"][:].T
|
|
193
|
+
self.x1r = h5file["node_coords"]["X"][:].T
|
|
194
|
+
self.x2r = h5file["node_coords"]["Y"][:].T
|
|
195
|
+
self.x3r = h5file["node_coords"]["Z"][:].T
|
|
196
|
+
self.GridAloneManager.readgridh5()
|
|
197
|
+
self.infogrid = False
|
|
198
|
+
|
|
199
|
+
# Close the file
|
|
200
|
+
h5file.close()
|
|
201
|
+
|
|
202
|
+
def offset_vtk(
|
|
203
|
+
self, i: int, var: str | None, exout: int, mm: mmap.mmap
|
|
204
|
+
) -> None:
|
|
205
|
+
"""Compute the offset and shape of the variables to be loaded.
|
|
206
|
+
|
|
207
|
+
The routine, knowing the grid shape, computes the offset and stores the
|
|
208
|
+
shape dependng on wether the variable is staggered or not.
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
-------
|
|
212
|
+
- None
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
- i (not optional): int
|
|
217
|
+
The index of the file to be loaded.
|
|
218
|
+
- var (not optional): str
|
|
219
|
+
The variable to be loaded.
|
|
220
|
+
|
|
221
|
+
----
|
|
222
|
+
|
|
223
|
+
Examples
|
|
224
|
+
--------
|
|
225
|
+
- Example #1: Load all the variables
|
|
226
|
+
|
|
227
|
+
>>> _offset_vtk(0, True)
|
|
228
|
+
|
|
229
|
+
"""
|
|
230
|
+
dir_map: dict[str, str] = {}
|
|
231
|
+
gridvars: list[str] = []
|
|
232
|
+
|
|
233
|
+
self.d_info["endianess"][exout] = (
|
|
234
|
+
">" if self.endian is None else self.d_info["endianess"][exout]
|
|
235
|
+
)
|
|
236
|
+
if self.d_info["endianess"][exout] is None:
|
|
237
|
+
raise ValueError("Error: Wrong endianess in vtk file.")
|
|
238
|
+
|
|
239
|
+
if self.alone is True:
|
|
240
|
+
self.d_info["binformat"][exout] = (
|
|
241
|
+
f"{self.d_info['endianess'][exout]}f{self.charsize}"
|
|
242
|
+
)
|
|
243
|
+
search_pos = 0
|
|
244
|
+
while True:
|
|
245
|
+
line_end = mm.find(b"\n", search_pos)
|
|
246
|
+
if line_end == -1:
|
|
247
|
+
break # No more occurrences found
|
|
248
|
+
line = mm[search_pos:line_end]
|
|
249
|
+
|
|
250
|
+
if line.startswith(b"SCALARS"):
|
|
251
|
+
parts = line.split()
|
|
252
|
+
namevar = parts[1].decode()
|
|
253
|
+
|
|
254
|
+
# Move to the start of the scalar data
|
|
255
|
+
lookup_table_pos = mm.find(b"LOOKUP_TABLE default", line_end)
|
|
256
|
+
offset = mm.find(b"\n", lookup_table_pos) + 1
|
|
257
|
+
|
|
258
|
+
self.varoffset[namevar] = offset
|
|
259
|
+
self.varshape[namevar] = self.nshp
|
|
260
|
+
if var is not None:
|
|
261
|
+
break
|
|
262
|
+
|
|
263
|
+
search_pos = offset + self.gridsize * self.charsize
|
|
264
|
+
|
|
265
|
+
elif line.startswith(b"VECTORS"):
|
|
266
|
+
# Handle VECTORS data
|
|
267
|
+
warnings.warn(
|
|
268
|
+
"Warning: VECTORS data is not supported.",
|
|
269
|
+
UserWarning,
|
|
270
|
+
stacklevel=2,
|
|
271
|
+
)
|
|
272
|
+
search_pos = line_end + 1
|
|
273
|
+
elif line.startswith(b"DIMENSIONS") and self.infogrid is True:
|
|
274
|
+
self.nx1, self.nx2, self.nx3 = [
|
|
275
|
+
max(int(i) - 1, 1) for i in line.split()[1:4]
|
|
276
|
+
]
|
|
277
|
+
if self.nx3 == 1 and self.nx2 == 1:
|
|
278
|
+
self.dim = 1
|
|
279
|
+
self.nshp = self.nx1
|
|
280
|
+
self.gridsize = self.nx1
|
|
281
|
+
nshp_grid = self.nx1 + 1
|
|
282
|
+
gridvars = ["x1r", "x2", "x3"]
|
|
283
|
+
elif self.nx3 == 1:
|
|
284
|
+
self.dim = 2
|
|
285
|
+
self.nshp = (self.nx2, self.nx1)
|
|
286
|
+
self.gridsize = self.nx1 * self.nx2
|
|
287
|
+
nshp_grid = (self.nx2 + 1, self.nx1 + 1)
|
|
288
|
+
gridvars = ["x1r", "x2r", "x3"]
|
|
289
|
+
else:
|
|
290
|
+
self.dim = 3
|
|
291
|
+
self.nshp = (self.nx3, self.nx2, self.nx1)
|
|
292
|
+
self.gridsize = self.nx1 * self.nx2 * self.nx3
|
|
293
|
+
nshp_grid = (self.nx3 + 1, self.nx2 + 1, self.nx1 + 1)
|
|
294
|
+
gridvars = ["x1r", "x2r", "x3r"]
|
|
295
|
+
dir_map = {"X": gridvars[0], "Y": gridvars[1], "Z": gridvars[2]}
|
|
296
|
+
search_pos = line_end + 1
|
|
297
|
+
elif line.startswith(b"TIME") and self.alone is True:
|
|
298
|
+
try:
|
|
299
|
+
parts = line.split()
|
|
300
|
+
binf = 8 if parts[3].decode() == "double" else 4
|
|
301
|
+
raw = mm[line_end + 1 : line_end + 1 + binf]
|
|
302
|
+
scrh = struct.unpack(
|
|
303
|
+
self.d_info["endianess"][exout] + "d", raw
|
|
304
|
+
)[0]
|
|
305
|
+
self.timelist[exout] = scrh
|
|
306
|
+
idx = np.searchsorted(self.noutlist, exout)
|
|
307
|
+
self.ntimelist[idx] = scrh
|
|
308
|
+
except Exception:
|
|
309
|
+
binf = 0
|
|
310
|
+
search_pos = line_end + 1 + binf
|
|
311
|
+
|
|
312
|
+
elif line[1:].startswith(b"_COORDINATES") and self.infogrid is True:
|
|
313
|
+
self.geom = "CARTESIAN"
|
|
314
|
+
linesplit = line.split()
|
|
315
|
+
var_sel = linesplit[0].decode()[0]
|
|
316
|
+
binf = (
|
|
317
|
+
self.d_info["endianess"][exout] + "d"
|
|
318
|
+
if linesplit[2].decode() == "double"
|
|
319
|
+
else self.d_info["endianess"][exout] + "f"
|
|
320
|
+
)
|
|
321
|
+
scrh = np.ndarray(
|
|
322
|
+
shape=int(linesplit[1]),
|
|
323
|
+
dtype=binf,
|
|
324
|
+
buffer=mm,
|
|
325
|
+
offset=line_end + 1,
|
|
326
|
+
order="C",
|
|
327
|
+
).T
|
|
328
|
+
setattr(self, dir_map[var_sel], scrh)
|
|
329
|
+
search_pos = line_end + 1
|
|
330
|
+
else:
|
|
331
|
+
search_pos = line_end + 1
|
|
332
|
+
|
|
333
|
+
if (
|
|
334
|
+
self.d_info["typefile"][exout] == "single_file"
|
|
335
|
+
and self.alone is True
|
|
336
|
+
):
|
|
337
|
+
self.d_info["varslist"][exout] = list(self.varoffset.keys())
|
|
338
|
+
if self.infogrid is True:
|
|
339
|
+
self.GridAloneManager.readgridvtk(gridvars)
|
|
340
|
+
self.infogrid = False
|
|
341
|
+
|
|
342
|
+
def offset_hdf5(
|
|
343
|
+
self, i: int, _var: str | None, exout: int, _mm: mmap.mmap
|
|
344
|
+
) -> None:
|
|
345
|
+
"""Load AMR data from PLUTO/Chombo HDF5 files.
|
|
346
|
+
|
|
347
|
+
This method is intentionally isolated from other formats.
|
|
348
|
+
"""
|
|
349
|
+
# Bridge AMR helpers (legacy naming) to the Newload state fields.
|
|
350
|
+
self._filepath = self.filepath
|
|
351
|
+
self._pathgrid = self.pathdir / Path("grid.out")
|
|
352
|
+
if not hasattr(self, "level"):
|
|
353
|
+
self.level = 0
|
|
354
|
+
|
|
355
|
+
# Keep the original varslist structure used by Newload internals.
|
|
356
|
+
varslist_table = self.d_info.get("varslist", None)
|
|
357
|
+
self._inspect_hdf5(i, exout)
|
|
358
|
+
|
|
359
|
+
# AMR reader stores a flat variable list; normalize as plain strings.
|
|
360
|
+
loaded_vars = []
|
|
361
|
+
for v in self.d_info.get("varslist", []):
|
|
362
|
+
loaded_vars.append(v.decode() if isinstance(v, bytes) else str(v))
|
|
363
|
+
|
|
364
|
+
if (
|
|
365
|
+
isinstance(varslist_table, list)
|
|
366
|
+
and len(varslist_table) > exout
|
|
367
|
+
and isinstance(varslist_table[exout], list | set | np.ndarray)
|
|
368
|
+
):
|
|
369
|
+
self.d_info["varslist"] = varslist_table
|
|
370
|
+
self.d_info["varslist"][exout] = loaded_vars
|
|
371
|
+
else:
|
|
372
|
+
self.d_info["varslist"] = loaded_vars
|
|
373
|
+
|
|
374
|
+
self.load_vars = loaded_vars
|
|
375
|
+
|
|
376
|
+
# Persist AMR metadata to state so Newload exposes it.
|
|
377
|
+
for amr_key in ("AMRLevel", "AMRBoxes", "Dt", "n1", "n2", "n3"):
|
|
378
|
+
if hasattr(self, amr_key):
|
|
379
|
+
setattr(self.state, amr_key, getattr(self, amr_key))
|
|
380
|
+
|
|
381
|
+
# Keep times aligned with nout/out tables when available.
|
|
382
|
+
try:
|
|
383
|
+
idx = np.searchsorted(self.outlist, exout)
|
|
384
|
+
self.timelist[idx] = float(self.ntime)
|
|
385
|
+
except Exception:
|
|
386
|
+
pass
|
|
387
|
+
try:
|
|
388
|
+
idx = np.searchsorted(self.noutlist, exout)
|
|
389
|
+
self.ntimelist[idx] = float(self.ntime)
|
|
390
|
+
except Exception:
|
|
391
|
+
pass
|
|
392
|
+
|
|
393
|
+
# Populate d_vars so Newload can expose loaded AMR variables normally.
|
|
394
|
+
for varname in loaded_vars:
|
|
395
|
+
if not hasattr(self, varname):
|
|
396
|
+
continue
|
|
397
|
+
data = getattr(self, varname)
|
|
398
|
+
self.varshape[varname] = np.shape(data)
|
|
399
|
+
self.varoffset[varname] = 0
|
|
400
|
+
|
|
401
|
+
if self.lennout != 1:
|
|
402
|
+
if varname not in self.d_vars:
|
|
403
|
+
self.d_vars[varname] = {}
|
|
404
|
+
self.d_vars[varname][exout] = data
|
|
405
|
+
else:
|
|
406
|
+
self.d_vars[varname] = data
|
|
407
|
+
|
|
408
|
+
self.infogrid = False
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import h5py
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def read_vtk(self) -> None:
|
|
9
|
+
"""Read the data from a VTK file.
|
|
10
|
+
|
|
11
|
+
Returns
|
|
12
|
+
-------
|
|
13
|
+
- None
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
- None
|
|
18
|
+
|
|
19
|
+
----
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
- Example #1: Read the data from a VTK file
|
|
24
|
+
|
|
25
|
+
>>> read_vtk()
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
raise NotImplementedError("read_vtk() is not yet implemented.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _read_h5(self, filename: str, **kwargs: Any) -> None:
|
|
32
|
+
"""Read the data from a HDF5 file.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
- the data in a dictionary
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
- filename: str
|
|
41
|
+
The name of the file to be read.
|
|
42
|
+
- kwargs: Any
|
|
43
|
+
Any additional arguments.
|
|
44
|
+
|
|
45
|
+
----
|
|
46
|
+
|
|
47
|
+
Examples
|
|
48
|
+
--------
|
|
49
|
+
- Example #1: Read the data from a HDF5 file
|
|
50
|
+
|
|
51
|
+
>>> read_h5("filename.h5")
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
# Create the path to the HDF5 file
|
|
55
|
+
try:
|
|
56
|
+
self._pathh5 = self.pathdir / filename
|
|
57
|
+
except FileNotFoundError:
|
|
58
|
+
self._pathh5 = filename
|
|
59
|
+
|
|
60
|
+
# Open the HDF5 file
|
|
61
|
+
data_dict = {}
|
|
62
|
+
with h5py.File(self._pathh5, "r") as f:
|
|
63
|
+
for key in f.keys():
|
|
64
|
+
data_dict[key] = f[key][()] # Store data in the dictionary
|
|
65
|
+
|
|
66
|
+
return data_dict # Return the dictionary
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def read_tab(self) -> None:
|
|
70
|
+
"""Read the data from a tab file.
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
- None
|
|
75
|
+
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
- None
|
|
79
|
+
|
|
80
|
+
----
|
|
81
|
+
|
|
82
|
+
Examples
|
|
83
|
+
--------
|
|
84
|
+
- Example #1: Read the data from a tab file
|
|
85
|
+
|
|
86
|
+
>>> read_tab()
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
raise NotImplementedError("read_tab() is not yet implemented.")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def read_bin(self) -> None:
|
|
93
|
+
"""Read the data from a binary file.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
- None
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
- None
|
|
102
|
+
|
|
103
|
+
----
|
|
104
|
+
|
|
105
|
+
Examples
|
|
106
|
+
--------
|
|
107
|
+
- Example #1: Read the data from a binary file
|
|
108
|
+
|
|
109
|
+
>>> read_bin()
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
raise NotImplementedError("read_bin() is not yet implemented.")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _read_dat(self, filename: str, **kwargs: Any) -> None:
|
|
116
|
+
"""Read the data from a dat file.
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
- The file columns as a dicionary
|
|
121
|
+
|
|
122
|
+
Parameters
|
|
123
|
+
----------
|
|
124
|
+
- filename (not optional): str
|
|
125
|
+
The name of the file to be read.
|
|
126
|
+
- kwargs: Any
|
|
127
|
+
Any additional arguments.
|
|
128
|
+
- names: bool, default True
|
|
129
|
+
If True, checks for column names in the file.
|
|
130
|
+
- skip: int, default 0
|
|
131
|
+
The number of rows to skip.
|
|
132
|
+
|
|
133
|
+
----
|
|
134
|
+
|
|
135
|
+
Examples
|
|
136
|
+
--------
|
|
137
|
+
- Example #1: Read the data from a dat file
|
|
138
|
+
|
|
139
|
+
>>> read_dat("filename.dat")
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
# Create the path to the HDF5 file
|
|
143
|
+
try:
|
|
144
|
+
self._pathh5 = self.pathdir / filename
|
|
145
|
+
except FileNotFoundError:
|
|
146
|
+
self._pathh5 = filename
|
|
147
|
+
|
|
148
|
+
names = kwargs.get("names", True)
|
|
149
|
+
skip = kwargs.get("skip", 0)
|
|
150
|
+
|
|
151
|
+
# Open the dat file with np.genfromtext
|
|
152
|
+
data = np.genfromtxt(self._pathh5, names=names, skip_header=skip)
|
|
153
|
+
if names:
|
|
154
|
+
loop = data.dtype.names
|
|
155
|
+
analysis = {name: data[name] for name in loop}
|
|
156
|
+
else:
|
|
157
|
+
loop = range(data.shape[1])
|
|
158
|
+
analysis = {f"col_{i}": data[:, i] for i in loop}
|
|
159
|
+
|
|
160
|
+
return analysis
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def read_file(
|
|
164
|
+
self, filename: str, datatype: str | None = None, **kwargs: Any
|
|
165
|
+
) -> Any:
|
|
166
|
+
"""Read the data from the output files.
|
|
167
|
+
|
|
168
|
+
Returns
|
|
169
|
+
-------
|
|
170
|
+
- the data as a dicionary
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
- filename (not optional): str
|
|
175
|
+
The name of the file to be read.
|
|
176
|
+
- datatype: str
|
|
177
|
+
The type of the file.
|
|
178
|
+
- **kwargs: Any
|
|
179
|
+
Any additional arguments.
|
|
180
|
+
|
|
181
|
+
----
|
|
182
|
+
|
|
183
|
+
Examples
|
|
184
|
+
--------
|
|
185
|
+
- Example #1: Read the data from the output files
|
|
186
|
+
|
|
187
|
+
>>> read_files()
|
|
188
|
+
|
|
189
|
+
"""
|
|
190
|
+
# Check the datatype of the input data
|
|
191
|
+
if datatype is None:
|
|
192
|
+
datatype = filename.rsplit(".", maxsplit=1)[-1]
|
|
193
|
+
poss_types = {"dbl", "flt", "vtk", "h5", "tab", "dat"}
|
|
194
|
+
if datatype not in poss_types:
|
|
195
|
+
warn = f"Invalid datatype: {datatype}. Resetting to 'h5'"
|
|
196
|
+
warnings.warn(warn)
|
|
197
|
+
datatype = "h5"
|
|
198
|
+
|
|
199
|
+
# Check the format of the output files
|
|
200
|
+
if datatype == "h5":
|
|
201
|
+
res = _read_h5(self, filename, **kwargs)
|
|
202
|
+
elif datatype == "dat":
|
|
203
|
+
res = _read_dat(self, filename, **kwargs)
|
|
204
|
+
else:
|
|
205
|
+
warn = (
|
|
206
|
+
f"Invalid datatype: {datatype}, not implemented yet! "
|
|
207
|
+
"Resetting to 'h5'"
|
|
208
|
+
)
|
|
209
|
+
warnings.warn(warn)
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
# End of the function
|
|
213
|
+
return res
|