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.

Files changed (108) hide show
  1. imas/__init__.py +34 -0
  2. imas/__main__.py +17 -0
  3. imas/_util.py +260 -0
  4. imas/_version.py +16 -0
  5. imas/assets/IDSDef2MDSpreTree.xsl +161 -0
  6. imas/assets/IDS_fake_toplevel.xml +318 -0
  7. imas/assets/IDS_minimal.xml +37 -0
  8. imas/assets/IDS_minimal_2.xml +37 -0
  9. imas/assets/IDS_minimal_struct_array.xml +43 -0
  10. imas/assets/IDS_minimal_types.xml +169 -0
  11. imas/assets/ITER_134173_106_core_profiles.ids +2438 -0
  12. imas/assets/ITER_134173_106_equilibrium.ids +3172 -0
  13. imas/assets/README.md +5 -0
  14. imas/assets/core_profiles.ids +2438 -0
  15. imas/assets/equilibrium.ids +3172 -0
  16. imas/backends/__init__.py +12 -0
  17. imas/backends/db_entry_impl.py +122 -0
  18. imas/backends/imas_core/__init__.py +4 -0
  19. imas/backends/imas_core/al_context.py +391 -0
  20. imas/backends/imas_core/db_entry_al.py +405 -0
  21. imas/backends/imas_core/db_entry_helpers.py +200 -0
  22. imas/backends/imas_core/imas_interface.py +216 -0
  23. imas/backends/imas_core/mdsplus_model.py +367 -0
  24. imas/backends/imas_core/uda_support.py +56 -0
  25. imas/backends/netcdf/__init__.py +4 -0
  26. imas/backends/netcdf/db_entry_nc.py +176 -0
  27. imas/backends/netcdf/ids2nc.py +306 -0
  28. imas/backends/netcdf/nc2ids.py +302 -0
  29. imas/backends/netcdf/nc_metadata.py +357 -0
  30. imas/backends/netcdf/nc_validate.py +53 -0
  31. imas/command/cli.py +239 -0
  32. imas/command/db_analysis.py +290 -0
  33. imas/command/helpers.py +45 -0
  34. imas/command/timer.py +77 -0
  35. imas/db_entry.py +802 -0
  36. imas/dd_helpers.py +300 -0
  37. imas/dd_zip.py +297 -0
  38. imas/exception.py +107 -0
  39. imas/ids_base.py +149 -0
  40. imas/ids_convert.py +920 -0
  41. imas/ids_coordinates.py +400 -0
  42. imas/ids_data_type.py +115 -0
  43. imas/ids_defs.py +171 -0
  44. imas/ids_factory.py +108 -0
  45. imas/ids_identifiers.py +125 -0
  46. imas/ids_metadata.py +307 -0
  47. imas/ids_path.py +254 -0
  48. imas/ids_primitive.py +510 -0
  49. imas/ids_struct_array.py +233 -0
  50. imas/ids_structure.py +331 -0
  51. imas/ids_toplevel.py +381 -0
  52. imas/setup_logging.py +64 -0
  53. imas/test/test_all_dd_versions.py +28 -0
  54. imas/test/test_cli.py +44 -0
  55. imas/test/test_dbentry.py +104 -0
  56. imas/test/test_dd_helpers.py +134 -0
  57. imas/test/test_dd_zip.py +29 -0
  58. imas/test/test_deepcopy.py +25 -0
  59. imas/test/test_exception.py +12 -0
  60. imas/test/test_get_sample.py +388 -0
  61. imas/test/test_hash.py +188 -0
  62. imas/test/test_helpers.py +354 -0
  63. imas/test/test_identifiers.py +105 -0
  64. imas/test/test_ids2nc.py +166 -0
  65. imas/test/test_ids_ascii_data.py +39 -0
  66. imas/test/test_ids_convert.py +415 -0
  67. imas/test/test_ids_coordinates.py +165 -0
  68. imas/test/test_ids_data_type.py +40 -0
  69. imas/test/test_ids_factory.py +35 -0
  70. imas/test/test_ids_metadata.py +66 -0
  71. imas/test/test_ids_mixin.py +20 -0
  72. imas/test/test_ids_path.py +192 -0
  73. imas/test/test_ids_primitive.py +109 -0
  74. imas/test/test_ids_struct_array.py +89 -0
  75. imas/test/test_ids_structure.py +70 -0
  76. imas/test/test_ids_toplevel.py +55 -0
  77. imas/test/test_ids_validate.py +343 -0
  78. imas/test/test_latest_dd_autofill.py +74 -0
  79. imas/test/test_latest_dd_manual.py +38 -0
  80. imas/test/test_latest_dd_resample.py +102 -0
  81. imas/test/test_lazy_loading.py +201 -0
  82. imas/test/test_list_occurrences.py +82 -0
  83. imas/test/test_minimal.py +37 -0
  84. imas/test/test_minimal_conversion.py +44 -0
  85. imas/test/test_minimal_io.py +21 -0
  86. imas/test/test_minimal_struct_array_io.py +60 -0
  87. imas/test/test_minimal_types.py +436 -0
  88. imas/test/test_minimal_types_io.py +70 -0
  89. imas/test/test_minimal_types_io_automatic.py +66 -0
  90. imas/test/test_nbc_change.py +408 -0
  91. imas/test/test_nc_autofill.py +13 -0
  92. imas/test/test_nc_entry.py +28 -0
  93. imas/test/test_nc_metadata.py +153 -0
  94. imas/test/test_nc_validation.py +197 -0
  95. imas/test/test_snippets.py +25 -0
  96. imas/test/test_static_ids.py +39 -0
  97. imas/test/test_str_1d.py +99 -0
  98. imas/test/test_time_slicing.py +182 -0
  99. imas/test/test_uda_support.py +12 -0
  100. imas/test/test_util.py +209 -0
  101. imas/training.py +45 -0
  102. imas/util.py +526 -0
  103. imas_python-0.1.dev1618.dist-info/LICENSE.txt +165 -0
  104. imas_python-0.1.dev1618.dist-info/METADATA +288 -0
  105. imas_python-0.1.dev1618.dist-info/RECORD +108 -0
  106. imas_python-0.1.dev1618.dist-info/WHEEL +5 -0
  107. imas_python-0.1.dev1618.dist-info/entry_points.txt +3 -0
  108. 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)