imas-python 0.1.dev1618__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.
Potentially problematic release.
This version of imas-python might be problematic. Click here for more details.
- imas/__init__.py +34 -0
- imas/__main__.py +17 -0
- imas/_util.py +260 -0
- imas/_version.py +16 -0
- imas/assets/IDSDef2MDSpreTree.xsl +161 -0
- imas/assets/IDS_fake_toplevel.xml +318 -0
- imas/assets/IDS_minimal.xml +37 -0
- imas/assets/IDS_minimal_2.xml +37 -0
- imas/assets/IDS_minimal_struct_array.xml +43 -0
- imas/assets/IDS_minimal_types.xml +169 -0
- imas/assets/ITER_134173_106_core_profiles.ids +2438 -0
- imas/assets/ITER_134173_106_equilibrium.ids +3172 -0
- imas/assets/README.md +5 -0
- imas/assets/core_profiles.ids +2438 -0
- imas/assets/equilibrium.ids +3172 -0
- imas/backends/__init__.py +12 -0
- imas/backends/db_entry_impl.py +122 -0
- imas/backends/imas_core/__init__.py +4 -0
- imas/backends/imas_core/al_context.py +391 -0
- imas/backends/imas_core/db_entry_al.py +405 -0
- imas/backends/imas_core/db_entry_helpers.py +200 -0
- imas/backends/imas_core/imas_interface.py +216 -0
- imas/backends/imas_core/mdsplus_model.py +367 -0
- imas/backends/imas_core/uda_support.py +56 -0
- imas/backends/netcdf/__init__.py +4 -0
- imas/backends/netcdf/db_entry_nc.py +176 -0
- imas/backends/netcdf/ids2nc.py +306 -0
- imas/backends/netcdf/nc2ids.py +302 -0
- imas/backends/netcdf/nc_metadata.py +357 -0
- imas/backends/netcdf/nc_validate.py +53 -0
- imas/command/cli.py +239 -0
- imas/command/db_analysis.py +290 -0
- imas/command/helpers.py +45 -0
- imas/command/timer.py +77 -0
- imas/db_entry.py +802 -0
- imas/dd_helpers.py +300 -0
- imas/dd_zip.py +297 -0
- imas/exception.py +107 -0
- imas/ids_base.py +149 -0
- imas/ids_convert.py +920 -0
- imas/ids_coordinates.py +400 -0
- imas/ids_data_type.py +115 -0
- imas/ids_defs.py +171 -0
- imas/ids_factory.py +108 -0
- imas/ids_identifiers.py +125 -0
- imas/ids_metadata.py +307 -0
- imas/ids_path.py +254 -0
- imas/ids_primitive.py +510 -0
- imas/ids_struct_array.py +233 -0
- imas/ids_structure.py +331 -0
- imas/ids_toplevel.py +381 -0
- imas/setup_logging.py +64 -0
- imas/test/test_all_dd_versions.py +28 -0
- imas/test/test_cli.py +44 -0
- imas/test/test_dbentry.py +104 -0
- imas/test/test_dd_helpers.py +134 -0
- imas/test/test_dd_zip.py +29 -0
- imas/test/test_deepcopy.py +25 -0
- imas/test/test_exception.py +12 -0
- imas/test/test_get_sample.py +388 -0
- imas/test/test_hash.py +188 -0
- imas/test/test_helpers.py +354 -0
- imas/test/test_identifiers.py +105 -0
- imas/test/test_ids2nc.py +166 -0
- imas/test/test_ids_ascii_data.py +39 -0
- imas/test/test_ids_convert.py +415 -0
- imas/test/test_ids_coordinates.py +165 -0
- imas/test/test_ids_data_type.py +40 -0
- imas/test/test_ids_factory.py +35 -0
- imas/test/test_ids_metadata.py +66 -0
- imas/test/test_ids_mixin.py +20 -0
- imas/test/test_ids_path.py +192 -0
- imas/test/test_ids_primitive.py +109 -0
- imas/test/test_ids_struct_array.py +89 -0
- imas/test/test_ids_structure.py +70 -0
- imas/test/test_ids_toplevel.py +55 -0
- imas/test/test_ids_validate.py +343 -0
- imas/test/test_latest_dd_autofill.py +74 -0
- imas/test/test_latest_dd_manual.py +38 -0
- imas/test/test_latest_dd_resample.py +102 -0
- imas/test/test_lazy_loading.py +201 -0
- imas/test/test_list_occurrences.py +82 -0
- imas/test/test_minimal.py +37 -0
- imas/test/test_minimal_conversion.py +44 -0
- imas/test/test_minimal_io.py +21 -0
- imas/test/test_minimal_struct_array_io.py +60 -0
- imas/test/test_minimal_types.py +436 -0
- imas/test/test_minimal_types_io.py +70 -0
- imas/test/test_minimal_types_io_automatic.py +66 -0
- imas/test/test_nbc_change.py +408 -0
- imas/test/test_nc_autofill.py +13 -0
- imas/test/test_nc_entry.py +28 -0
- imas/test/test_nc_metadata.py +153 -0
- imas/test/test_nc_validation.py +197 -0
- imas/test/test_snippets.py +25 -0
- imas/test/test_static_ids.py +39 -0
- imas/test/test_str_1d.py +99 -0
- imas/test/test_time_slicing.py +182 -0
- imas/test/test_uda_support.py +12 -0
- imas/test/test_util.py +209 -0
- imas/training.py +45 -0
- imas/util.py +526 -0
- imas_python-0.1.dev1618.dist-info/LICENSE.txt +165 -0
- imas_python-0.1.dev1618.dist-info/METADATA +288 -0
- imas_python-0.1.dev1618.dist-info/RECORD +108 -0
- imas_python-0.1.dev1618.dist-info/WHEEL +5 -0
- imas_python-0.1.dev1618.dist-info/entry_points.txt +3 -0
- imas_python-0.1.dev1618.dist-info/top_level.txt +1 -0
imas/test/test_util.py
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
import imas
|
|
4
|
+
from imas.db_entry import DBEntry
|
|
5
|
+
from imas.ids_defs import MEMORY_BACKEND
|
|
6
|
+
from imas.test.test_helpers import fill_consistent
|
|
7
|
+
from imas.training import get_training_db_entry
|
|
8
|
+
from imas.util import (
|
|
9
|
+
find_paths,
|
|
10
|
+
get_data_dictionary_version,
|
|
11
|
+
get_full_path,
|
|
12
|
+
get_parent,
|
|
13
|
+
get_time_mode,
|
|
14
|
+
get_toplevel,
|
|
15
|
+
idsdiffgen,
|
|
16
|
+
inspect,
|
|
17
|
+
is_lazy_loaded,
|
|
18
|
+
print_metadata_tree,
|
|
19
|
+
print_tree,
|
|
20
|
+
tree_iter,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_tree_iter():
|
|
25
|
+
cp = imas.IDSFactory("3.39.0").new("core_profiles")
|
|
26
|
+
|
|
27
|
+
# Test tree iterator over empty IDS
|
|
28
|
+
assert list(tree_iter(cp)) == []
|
|
29
|
+
assert list(tree_iter(cp, leaf_only=False)) == []
|
|
30
|
+
assert list(tree_iter(cp, leaf_only=False, include_node=True)) == [cp]
|
|
31
|
+
|
|
32
|
+
# Fill some data and test again
|
|
33
|
+
cp.ids_properties.homogeneous_time = 1
|
|
34
|
+
ht = cp.ids_properties.homogeneous_time
|
|
35
|
+
assert list(tree_iter(cp)) == [ht]
|
|
36
|
+
assert list(tree_iter(cp, leaf_only=False)) == [cp.ids_properties, ht]
|
|
37
|
+
expected = [cp, cp.ids_properties, ht]
|
|
38
|
+
assert list(tree_iter(cp, leaf_only=False, include_node=True)) == expected
|
|
39
|
+
|
|
40
|
+
# Test if empty values are iterated over as expected
|
|
41
|
+
visit_empty = list(tree_iter(cp.ids_properties, visit_empty=True))
|
|
42
|
+
ip = cp.ids_properties
|
|
43
|
+
assert visit_empty[:4] == [ip.comment, ht, ip.source, ip.provider]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_inspect():
|
|
47
|
+
cp = imas.IDSFactory("3.39.0").new("core_profiles")
|
|
48
|
+
inspect(cp) # IDSToplevel
|
|
49
|
+
inspect(cp.ids_properties) # IDSStructure
|
|
50
|
+
cp.profiles_1d.resize(5)
|
|
51
|
+
inspect(cp.profiles_1d) # IDSStructArray
|
|
52
|
+
inspect(cp.profiles_1d[1]) # IDSStructure inside array
|
|
53
|
+
inspect(cp.profiles_1d[1].grid) # IDSStructure inside array
|
|
54
|
+
inspect(cp.profiles_1d[1].grid.rho_tor_norm) # IDSPrimitive
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_inspect_lazy():
|
|
58
|
+
with get_training_db_entry() as entry:
|
|
59
|
+
cp = entry.get("core_profiles", lazy=True)
|
|
60
|
+
inspect(cp)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_print_tree():
|
|
64
|
+
cp = imas.IDSFactory("3.39.0").new("core_profiles")
|
|
65
|
+
fill_consistent(cp)
|
|
66
|
+
print_tree(cp) # Full IDS tree
|
|
67
|
+
print_tree(cp.ids_properties) # Sub-tree
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_print_metadata_tree():
|
|
71
|
+
cp = imas.IDSFactory("3.39.0").new("core_profiles")
|
|
72
|
+
print_metadata_tree(cp, 1)
|
|
73
|
+
print_metadata_tree(cp.metadata, 1)
|
|
74
|
+
print_metadata_tree(cp.metadata["ids_properties"], 0)
|
|
75
|
+
print_metadata_tree(cp.metadata["profiles_1d/electrons"])
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_find_paths():
|
|
79
|
+
cp = imas.IDSFactory("3.39.0").new("core_profiles")
|
|
80
|
+
matches = find_paths(cp, "(^|/)time$")
|
|
81
|
+
assert matches == ["profiles_1d/time", "profiles_2d/time", "time"]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_idsdiffgen():
|
|
85
|
+
factory1 = imas.IDSFactory("3.39.0")
|
|
86
|
+
factory2 = imas.IDSFactory("3.32.0")
|
|
87
|
+
cp1 = factory1.new("core_profiles")
|
|
88
|
+
cp2 = factory2.new("core_profiles")
|
|
89
|
+
eq1 = factory1.new("equilibrium")
|
|
90
|
+
|
|
91
|
+
# Test different DD versions
|
|
92
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
93
|
+
assert len(diff) == 1
|
|
94
|
+
assert diff[0][1:] == ("3.39.0", "3.32.0")
|
|
95
|
+
|
|
96
|
+
# Test different IDSs
|
|
97
|
+
diff = list(idsdiffgen(cp1, eq1))
|
|
98
|
+
assert len(diff) == 1
|
|
99
|
+
assert diff[0][1:] == ("core_profiles", "equilibrium")
|
|
100
|
+
|
|
101
|
+
cp2 = factory1.new("core_profiles")
|
|
102
|
+
# Test different structures
|
|
103
|
+
cp2.ids_properties.homogeneous_time = 1
|
|
104
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
105
|
+
assert len(diff) == 1
|
|
106
|
+
assert diff[0] == ("ids_properties/homogeneous_time", None, 1)
|
|
107
|
+
|
|
108
|
+
# Test different values
|
|
109
|
+
cp1.ids_properties.homogeneous_time = 2
|
|
110
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
111
|
+
assert len(diff) == 1
|
|
112
|
+
assert diff[0] == ("ids_properties/homogeneous_time", 2, 1)
|
|
113
|
+
|
|
114
|
+
cp1.ids_properties.homogeneous_time = 1
|
|
115
|
+
# Test missing values
|
|
116
|
+
cp1.time = [1.0, 2.0]
|
|
117
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
118
|
+
assert len(diff) == 1
|
|
119
|
+
assert diff[0] == ("time", cp1.time, None)
|
|
120
|
+
|
|
121
|
+
# Test different array values
|
|
122
|
+
cp2.time = [2.0, 1.0]
|
|
123
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
124
|
+
assert len(diff) == 1
|
|
125
|
+
assert diff[0] == ("time", cp1.time, cp2.time)
|
|
126
|
+
|
|
127
|
+
cp2.time = cp1.time
|
|
128
|
+
# Test different AoS lengths
|
|
129
|
+
cp1.profiles_1d.resize(1)
|
|
130
|
+
cp2.profiles_1d.resize(2)
|
|
131
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
132
|
+
assert len(diff) == 1
|
|
133
|
+
assert diff[0] == ("profiles_1d", cp1.profiles_1d, cp2.profiles_1d)
|
|
134
|
+
|
|
135
|
+
# Test different values inside AoS
|
|
136
|
+
cp2.profiles_1d.resize(1)
|
|
137
|
+
cp1.profiles_1d[0].time = -1
|
|
138
|
+
cp2.profiles_1d[0].time = 0
|
|
139
|
+
diff = list(idsdiffgen(cp1, cp2))
|
|
140
|
+
assert len(diff) == 1
|
|
141
|
+
assert diff[0] == ("profiles_1d/time", -1, 0)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_idsdiff():
|
|
145
|
+
# Test the diff rendering for two sample IDSs
|
|
146
|
+
with get_training_db_entry() as entry:
|
|
147
|
+
imas.util.idsdiff(entry.get("core_profiles"), entry.get("equilibrium"))
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_get_parent():
|
|
151
|
+
cp = imas.IDSFactory("3.39.0").core_profiles()
|
|
152
|
+
cp.profiles_1d.resize(2)
|
|
153
|
+
assert (
|
|
154
|
+
get_parent(cp.profiles_1d[0].electrons.temperature)
|
|
155
|
+
is cp.profiles_1d[0].electrons
|
|
156
|
+
)
|
|
157
|
+
assert get_parent(cp.profiles_1d[0].electrons) is cp.profiles_1d[0]
|
|
158
|
+
assert get_parent(cp.profiles_1d[0]) is cp.profiles_1d
|
|
159
|
+
assert get_parent(cp.profiles_1d) is cp
|
|
160
|
+
assert get_parent(cp) is None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def test_get_time_mode():
|
|
164
|
+
cp = imas.IDSFactory("3.39.0").core_profiles()
|
|
165
|
+
cp.profiles_1d.resize(2)
|
|
166
|
+
assert (
|
|
167
|
+
get_time_mode(cp.profiles_1d[0].electrons.temperature)
|
|
168
|
+
is cp.ids_properties.homogeneous_time
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def test_get_toplevel():
|
|
173
|
+
cp = imas.IDSFactory("3.39.0").core_profiles()
|
|
174
|
+
cp.profiles_1d.resize(2)
|
|
175
|
+
assert get_toplevel(cp.profiles_1d[0].electrons.temperature) is cp
|
|
176
|
+
assert get_toplevel(cp.profiles_1d[0].electrons) is cp
|
|
177
|
+
assert get_toplevel(cp.profiles_1d[0]) is cp
|
|
178
|
+
assert get_toplevel(cp.profiles_1d) is cp
|
|
179
|
+
assert get_toplevel(cp) is cp
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_is_lazy_loaded():
|
|
183
|
+
with get_training_db_entry() as entry:
|
|
184
|
+
assert is_lazy_loaded(entry.get("core_profiles")) is False
|
|
185
|
+
assert is_lazy_loaded(entry.get("core_profiles", lazy=True)) is True
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def test_get_full_path():
|
|
189
|
+
cp = imas.IDSFactory("3.39.0").core_profiles()
|
|
190
|
+
cp.profiles_1d.resize(2)
|
|
191
|
+
assert (
|
|
192
|
+
get_full_path(cp.profiles_1d[1].electrons.temperature)
|
|
193
|
+
== "profiles_1d[1]/electrons/temperature"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@pytest.mark.parametrize("version", ["3.31.0", "3.39.0"])
|
|
198
|
+
def test_get_dd_version(version):
|
|
199
|
+
entry = DBEntry(MEMORY_BACKEND, "test", 0, 0, dd_version=version)
|
|
200
|
+
assert get_data_dictionary_version(entry) == version
|
|
201
|
+
assert get_data_dictionary_version(entry.factory) == version
|
|
202
|
+
|
|
203
|
+
cp = entry.factory.core_profiles()
|
|
204
|
+
cp.profiles_1d.resize(2)
|
|
205
|
+
assert get_data_dictionary_version(cp.profiles_1d[0].electrons) == version
|
|
206
|
+
assert get_data_dictionary_version(cp.profiles_1d[0]) == version
|
|
207
|
+
assert get_data_dictionary_version(cp.profiles_1d) == version
|
|
208
|
+
assert get_data_dictionary_version(cp) == version
|
|
209
|
+
assert get_data_dictionary_version(cp.time) == version
|
imas/training.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# This file is part of imas-python.
|
|
2
|
+
# You should have received the imas-python LICENSE file with this project.
|
|
3
|
+
"""Functions that are useful for the imas-python training courses.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import importlib
|
|
7
|
+
from unittest.mock import patch
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from importlib.resources import files
|
|
11
|
+
except ImportError: # Python 3.8 support
|
|
12
|
+
from importlib_resources import files
|
|
13
|
+
|
|
14
|
+
import imas
|
|
15
|
+
from imas.backends.imas_core.imas_interface import ll_interface
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _initialize_training_db(DBEntry_cls):
|
|
19
|
+
assets_path = files(imas) / "assets/"
|
|
20
|
+
pulse, run, user, database = 134173, 106, "public", "ITER"
|
|
21
|
+
if ll_interface._al_version.major == 4:
|
|
22
|
+
entry = DBEntry_cls(imas.ids_defs.ASCII_BACKEND, database, pulse, run, user)
|
|
23
|
+
entry.open(options=f"-prefix {assets_path}/")
|
|
24
|
+
else:
|
|
25
|
+
entry = DBEntry_cls(f"imas:ascii?path={assets_path}", "r")
|
|
26
|
+
|
|
27
|
+
output_entry = DBEntry_cls(imas.ids_defs.MEMORY_BACKEND, database, pulse, run)
|
|
28
|
+
output_entry.create()
|
|
29
|
+
for ids_name in ["core_profiles", "equilibrium"]:
|
|
30
|
+
ids = entry.get(ids_name)
|
|
31
|
+
with patch.dict("os.environ", {"IMAS_AL_DISABLE_VALIDATE": "1"}):
|
|
32
|
+
output_entry.put(ids)
|
|
33
|
+
entry.close()
|
|
34
|
+
return output_entry
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_training_db_entry() -> imas.DBEntry:
|
|
38
|
+
"""Open and return an ``imas.DBEntry`` pointing to the training data."""
|
|
39
|
+
return _initialize_training_db(imas.DBEntry)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_training_imas_db_entry():
|
|
43
|
+
"""Open and return an ``imas.DBEntry`` pointing to the training data."""
|
|
44
|
+
imas = importlib.import_module("imas")
|
|
45
|
+
return _initialize_training_db(imas.DBEntry)
|