Skip to content

Commit eabbecf

Browse files
committed
Add tests for netcdf lazy loading and fix implementation bugs
1 parent 7ab02c7 commit eabbecf

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

imas/backends/netcdf/nc2ids.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -362,37 +362,32 @@ def get_child(self, child):
362362
metadata = child.metadata
363363
path = metadata.path_string
364364
data_type = metadata.data_type
365+
nc2ids = self.nc2ids
366+
var = nc2ids._lazy_map.get(path)
365367

366-
var = self.nc2ids._lazy_map.get(path)
367368
if data_type is IDSDataType.STRUCT_ARRAY:
368369
# Determine size of the aos
369370
if var is None:
370371
size = 0
371372
elif "sparse" in var.ncattrs():
372-
size = self.group[var.name + ":shape"][self.index][0]
373+
size = nc2ids.group[var.name + ":shape"][self.index][0]
373374
else:
374375
# FIXME: extract dimension name from nc file?
375-
dim = self.ncmeta.get_dimensions(
376-
metadata.path_string, self.homogeneous_time
376+
dim = nc2ids.ncmeta.get_dimensions(
377+
metadata.path_string, nc2ids.homogeneous_time
377378
)[-1]
378-
size = self.group.dimensions[dim].size
379+
size = nc2ids.group.dimensions[dim].size
379380

380-
child._set_lazy_context(
381-
LazyArrayStructContext(self.nc2ids, self.index, size)
382-
)
381+
child._set_lazy_context(LazyArrayStructContext(nc2ids, self.index, size))
383382

384383
elif data_type is IDSDataType.STRUCTURE:
385384
child._set_lazy_context(self)
386385

387-
else: # Data elements
388-
var = self.nc2ids._lazy_map.get(path)
389-
if var is None:
390-
return # nothing to load
391-
386+
elif var is not None: # Data elements
392387
value = None
393388
if "sparse" in var.ncattrs():
394389
if metadata.ndim:
395-
shape_var = self.nc2ids.group[var.name + ":shape"]
390+
shape_var = nc2ids.group[var.name + ":shape"]
396391
shape = shape_var[self.index]
397392
if shape.all():
398393
value = var[self.index + tuple(map(slice, shape))]

imas/test/test_lazy_loading.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import numpy
55
import pytest
6-
76
from imas.backends.imas_core.imas_interface import ll_interface
87
from imas.db_entry import DBEntry
98
from imas.ids_defs import (
@@ -22,6 +21,15 @@ def test_lazy_load_aos(backend, worker_id, tmp_path, log_lowlevel_calls):
2221
if backend == ASCII_BACKEND:
2322
pytest.skip("Lazy loading is not supported by the ASCII backend.")
2423
dbentry = open_dbentry(backend, "w", worker_id, tmp_path, dd_version="3.39.0")
24+
run_lazy_load_aos(dbentry)
25+
26+
27+
def test_lazy_load_aos_netcdf(tmp_path):
28+
dbentry = DBEntry(str(tmp_path / "lazy_load_aos.nc"), "x", dd_version="3.39.0")
29+
run_lazy_load_aos(dbentry)
30+
31+
32+
def run_lazy_load_aos(dbentry):
2533
ids = dbentry.factory.new("core_profiles")
2634
ids.ids_properties.homogeneous_time = IDS_TIME_MODE_HETEROGENEOUS
2735
ids.profiles_1d.resize(10)
@@ -46,9 +54,12 @@ def test_lazy_load_aos(backend, worker_id, tmp_path, log_lowlevel_calls):
4654
assert values[method].call_count == 0
4755

4856
# Test get_slice
49-
lazy_ids_slice = dbentry.get_slice("core_profiles", 3.5, PREVIOUS_INTERP, lazy=True)
50-
assert lazy_ids_slice.profiles_1d.shape == (1,)
51-
assert lazy_ids_slice.profiles_1d[0].time == 3
57+
try:
58+
lazy_slice = dbentry.get_slice("core_profiles", 3.5, PREVIOUS_INTERP, lazy=True)
59+
assert lazy_slice.profiles_1d.shape == (1,)
60+
assert lazy_slice.profiles_1d[0].time == 3
61+
except NotImplementedError:
62+
pass # netCDF backend doesn't implement get_slice
5263

5364
dbentry.close()
5465

@@ -57,6 +68,15 @@ def test_lazy_loading_distributions_random(backend, worker_id, tmp_path):
5768
if backend == ASCII_BACKEND:
5869
pytest.skip("Lazy loading is not supported by the ASCII backend.")
5970
dbentry = open_dbentry(backend, "w", worker_id, tmp_path)
71+
run_lazy_loading_distributions_random(dbentry)
72+
73+
74+
def test_lazy_loading_distributions_random_netcdf(tmp_path):
75+
dbentry = DBEntry(str(tmp_path / "lazy_load_distributions.nc"), "x")
76+
run_lazy_loading_distributions_random(dbentry)
77+
78+
79+
def run_lazy_loading_distributions_random(dbentry):
6080
ids = IDSFactory().new("distributions")
6181
fill_consistent(ids)
6282
dbentry.put(ids)
@@ -92,7 +112,15 @@ def test_lazy_load_close_dbentry(requires_imas):
92112
def test_lazy_load_readonly(requires_imas):
93113
dbentry = DBEntry(MEMORY_BACKEND, "ITER", 1, 1)
94114
dbentry.create()
115+
run_lazy_load_readonly(dbentry)
116+
117+
118+
def test_lazy_load_readonly_netcdf(tmp_path):
119+
dbentry = DBEntry(str(tmp_path / "lazy_load_readonly.nc"), "x")
120+
run_lazy_load_readonly(dbentry)
95121

122+
123+
def run_lazy_load_readonly(dbentry):
96124
ids = dbentry.factory.core_profiles()
97125
ids.ids_properties.homogeneous_time = IDS_TIME_MODE_HETEROGENEOUS
98126
ids.time = [1, 2]
@@ -165,6 +193,27 @@ def test_lazy_load_with_new_aos(requires_imas):
165193
dbentry.close()
166194

167195

196+
def test_lazy_load_with_new_aos_netcdf(tmp_path):
197+
fname = str(tmp_path / "new_aos.nc")
198+
with DBEntry(fname, "x", dd_version="3.30.0") as dbentry:
199+
et = dbentry.factory.edge_transport()
200+
201+
et.ids_properties.homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS
202+
et.time = [1.0]
203+
et.model.resize(1)
204+
et.model[0].ggd.resize(1)
205+
et.model[0].ggd[0].electrons.particles.d.resize(1)
206+
et.model[0].ggd[0].electrons.particles.d[0].grid_index = -1
207+
dbentry.put(et)
208+
209+
with DBEntry(fname, "r", dd_version="3.39.0") as entry2:
210+
lazy_et = entry2.get("edge_transport", lazy=True)
211+
assert numpy.array_equal(lazy_et.time, [1.0])
212+
assert lazy_et.model[0].ggd[0].electrons.particles.d[0].grid_index == -1
213+
# d_radial did not exist in 3.30.0
214+
assert len(lazy_et.model[0].ggd[0].electrons.particles.d_radial) == 0
215+
216+
168217
def test_lazy_load_with_new_structure(requires_imas):
169218
dbentry = DBEntry(MEMORY_BACKEND, "ITER", 1, 1, dd_version="3.30.0")
170219
dbentry.create()

0 commit comments

Comments
 (0)