imas-python 2.0.1__tar.gz → 2.1.0__tar.gz

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.
Files changed (225) hide show
  1. {imas_python-2.0.1 → imas_python-2.1.0}/.github/workflows/test_with_pytest.yml +2 -4
  2. {imas_python-2.0.1 → imas_python-2.1.0}/PKG-INFO +2 -1
  3. {imas_python-2.0.1 → imas_python-2.1.0}/benchmarks/core_profiles.py +49 -54
  4. {imas_python-2.0.1 → imas_python-2.1.0}/benchmarks/edge_profiles.py +20 -25
  5. {imas_python-2.0.1 → imas_python-2.1.0}/benchmarks/utils.py +8 -24
  6. {imas_python-2.0.1 → imas_python-2.1.0}/conftest.py +7 -0
  7. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/changelog.rst +40 -2
  8. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/cli.rst +2 -2
  9. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/conf.py +4 -4
  10. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/analyze.rst +4 -9
  11. imas_python-2.1.0/docs/source/examples/custom_conversion_em_coupling.py +168 -0
  12. imas_python-2.1.0/docs/source/examples/custom_conversion_em_coupling.rst +13 -0
  13. imas_python-2.1.0/docs/source/examples.rst +14 -0
  14. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/identifiers.rst +100 -5
  15. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/index.rst +1 -0
  16. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/lazy_loading.rst +10 -1
  17. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/multi-dd.rst +92 -1
  18. {imas_python-2.0.1 → imas_python-2.1.0}/imas/_version.py +16 -3
  19. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/al_context.py +1 -4
  20. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/db_entry_al.py +67 -91
  21. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/imas_interface.py +6 -32
  22. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/mdsplus_model.py +0 -22
  23. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/nc2ids.py +6 -3
  24. {imas_python-2.0.1 → imas_python-2.1.0}/imas/command/cli.py +0 -1
  25. {imas_python-2.0.1 → imas_python-2.1.0}/imas/command/db_analysis.py +102 -7
  26. {imas_python-2.0.1 → imas_python-2.1.0}/imas/command/helpers.py +1 -1
  27. {imas_python-2.0.1 → imas_python-2.1.0}/imas/db_entry.py +35 -35
  28. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_convert.py +324 -39
  29. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_coordinates.py +4 -3
  30. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_factory.py +8 -5
  31. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_identifiers.py +30 -15
  32. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_structure.py +4 -3
  33. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_toplevel.py +8 -17
  34. imas_python-2.1.0/imas/test/test_cli.py +102 -0
  35. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_dbentry.py +1 -6
  36. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_helpers.py +66 -55
  37. imas_python-2.1.0/imas/test/test_identifiers.py +295 -0
  38. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_convert.py +215 -0
  39. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_lazy_loading.py +4 -2
  40. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_time_slicing.py +0 -7
  41. imas_python-2.1.0/imas/training.py +26 -0
  42. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/PKG-INFO +2 -1
  43. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/SOURCES.txt +3 -0
  44. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/requires.txt +1 -0
  45. {imas_python-2.0.1 → imas_python-2.1.0}/pyproject.toml +1 -0
  46. imas_python-2.0.1/imas/test/test_cli.py +0 -50
  47. imas_python-2.0.1/imas/test/test_identifiers.py +0 -105
  48. imas_python-2.0.1/imas/training.py +0 -45
  49. {imas_python-2.0.1 → imas_python-2.1.0}/.git-blame-ignore-revs +0 -0
  50. {imas_python-2.0.1 → imas_python-2.1.0}/.git_archival.txt +0 -0
  51. {imas_python-2.0.1 → imas_python-2.1.0}/.gitattributes +0 -0
  52. {imas_python-2.0.1 → imas_python-2.1.0}/.github/CODEOWNERS +0 -0
  53. {imas_python-2.0.1 → imas_python-2.1.0}/.github/workflows/linting.yml +0 -0
  54. {imas_python-2.0.1 → imas_python-2.1.0}/.github/workflows/publish.yml +0 -0
  55. {imas_python-2.0.1 → imas_python-2.1.0}/.github/workflows/verify_sphinx_doc.yml +0 -0
  56. {imas_python-2.0.1 → imas_python-2.1.0}/.gitignore +0 -0
  57. {imas_python-2.0.1 → imas_python-2.1.0}/.pylintrc +0 -0
  58. {imas_python-2.0.1 → imas_python-2.1.0}/.readthedocs.yml +0 -0
  59. {imas_python-2.0.1 → imas_python-2.1.0}/CODE_OF_CONDUCT.md +0 -0
  60. {imas_python-2.0.1 → imas_python-2.1.0}/CONTRIBUTING.md +0 -0
  61. {imas_python-2.0.1 → imas_python-2.1.0}/LICENSE.txt +0 -0
  62. {imas_python-2.0.1 → imas_python-2.1.0}/MANIFEST.in +0 -0
  63. {imas_python-2.0.1 → imas_python-2.1.0}/README.md +0 -0
  64. {imas_python-2.0.1 → imas_python-2.1.0}/asv.conf.json +0 -0
  65. {imas_python-2.0.1 → imas_python-2.1.0}/benchmarks/__init__.py +0 -0
  66. {imas_python-2.0.1 → imas_python-2.1.0}/benchmarks/technical.py +0 -0
  67. {imas_python-2.0.1 → imas_python-2.1.0}/docs/.gitignore +0 -0
  68. {imas_python-2.0.1 → imas_python-2.1.0}/docs/Makefile +0 -0
  69. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/.gitignore +0 -0
  70. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_static/imas.css +0 -0
  71. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_static/imas_200x200.png +0 -0
  72. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/autosummary/accessor.rst +0 -0
  73. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/autosummary/accessor_attribute.rst +0 -0
  74. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/autosummary/accessor_callable.rst +0 -0
  75. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/autosummary/accessor_method.rst +0 -0
  76. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/autosummary/base.rst +0 -0
  77. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/custom-class-template.rst +0 -0
  78. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/custom-module-template.rst +0 -0
  79. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/_templates/layout.html +0 -0
  80. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/api-hidden.rst +0 -0
  81. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/api.rst +0 -0
  82. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/benchmarking.rst +0 -0
  83. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/ci_config.rst +0 -0
  84. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/code_style.rst +0 -0
  85. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/configuring.rst +0 -0
  86. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/dd_versions.rst +0 -0
  87. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/explore.rst +0 -0
  88. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/hashing.rst +0 -0
  89. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/alternative_coordinates.py +0 -0
  90. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/autoconvert_get.py +0 -0
  91. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/autoconvert_put.py +0 -0
  92. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/calc_with_units.py +0 -0
  93. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/coordinates.py +0 -0
  94. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/dd_versions.py +0 -0
  95. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/explore_data.py +0 -0
  96. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/explore_structures.py +0 -0
  97. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/hashing.py +0 -0
  98. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/ids_convert.py +0 -0
  99. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/ids_to_xarray.py +0 -0
  100. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/imas_snippets/tensorized_ids_to_xarray.py +0 -0
  101. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/metadata.rst +0 -0
  102. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced/xarray.rst +0 -0
  103. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/advanced_user_training.rst +0 -0
  104. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/core_profiles_ne_timeslice.png +0 -0
  105. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/core_profiles_te.png +0 -0
  106. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/create.rst +0 -0
  107. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/explore.rst +0 -0
  108. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_inspect.png +0 -0
  109. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/create_core_profiles.py +0 -0
  110. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/explore_data_entry.py +0 -0
  111. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/explore_public_ec_launchers.py +0 -0
  112. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/explore_public_pf_active.py +0 -0
  113. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/explore_training_data.py +0 -0
  114. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/find_paths.py +0 -0
  115. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/iterate_core_profiles.py +0 -0
  116. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/plot_core_profiles_ne_timeslice.py +0 -0
  117. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/plot_core_profiles_te.py +0 -0
  118. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/print_idss.py +0 -0
  119. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/read_core_profiles_ne_timeslice.py +0 -0
  120. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/read_equilibrium_time_array.py +0 -0
  121. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/read_whole_equilibrium.py +0 -0
  122. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/imas_snippets/transform_grid.py +0 -0
  123. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/interactive_tab_core_profiles_toplevel.png +0 -0
  124. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/print_tree_ids_properties.png +0 -0
  125. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/setup.rst +0 -0
  126. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic/transform.rst +0 -0
  127. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/courses/basic_user_training.rst +0 -0
  128. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/imas_architecture.rst +0 -0
  129. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/imas_structure.png +0 -0
  130. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/installing.rst +0 -0
  131. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/intro.rst +0 -0
  132. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/mdsplus.rst +0 -0
  133. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/metadata.rst +0 -0
  134. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/netcdf/conventions.rst +0 -0
  135. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/netcdf.rst +0 -0
  136. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/release_imas.rst +0 -0
  137. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/resampling.rst +0 -0
  138. {imas_python-2.0.1 → imas_python-2.1.0}/docs/source/validation.rst +0 -0
  139. {imas_python-2.0.1 → imas_python-2.1.0}/imas/__init__.py +0 -0
  140. {imas_python-2.0.1 → imas_python-2.1.0}/imas/__main__.py +0 -0
  141. {imas_python-2.0.1 → imas_python-2.1.0}/imas/_to_xarray.py +0 -0
  142. {imas_python-2.0.1 → imas_python-2.1.0}/imas/_util.py +0 -0
  143. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDSDef2MDSpreTree.xsl +0 -0
  144. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDS_fake_toplevel.xml +0 -0
  145. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDS_minimal.xml +0 -0
  146. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDS_minimal_2.xml +0 -0
  147. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDS_minimal_struct_array.xml +0 -0
  148. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/IDS_minimal_types.xml +0 -0
  149. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/ITER_134173_106_core_profiles.ids +0 -0
  150. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/ITER_134173_106_equilibrium.ids +0 -0
  151. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/README.md +0 -0
  152. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/core_profiles.ids +0 -0
  153. {imas_python-2.0.1 → imas_python-2.1.0}/imas/assets/equilibrium.ids +0 -0
  154. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/__init__.py +0 -0
  155. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/db_entry_impl.py +0 -0
  156. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/__init__.py +0 -0
  157. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/db_entry_helpers.py +0 -0
  158. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/imas_core/uda_support.py +0 -0
  159. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/__init__.py +0 -0
  160. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/db_entry_nc.py +0 -0
  161. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/ids2nc.py +0 -0
  162. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/ids_tensorizer.py +0 -0
  163. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/iterators.py +0 -0
  164. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/nc_metadata.py +0 -0
  165. {imas_python-2.0.1 → imas_python-2.1.0}/imas/backends/netcdf/nc_validate.py +0 -0
  166. {imas_python-2.0.1 → imas_python-2.1.0}/imas/command/timer.py +0 -0
  167. {imas_python-2.0.1 → imas_python-2.1.0}/imas/dd_zip.py +0 -0
  168. {imas_python-2.0.1 → imas_python-2.1.0}/imas/exception.py +0 -0
  169. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_base.py +0 -0
  170. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_data_type.py +0 -0
  171. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_defs.py +0 -0
  172. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_metadata.py +0 -0
  173. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_path.py +0 -0
  174. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_primitive.py +0 -0
  175. {imas_python-2.0.1 → imas_python-2.1.0}/imas/ids_struct_array.py +0 -0
  176. {imas_python-2.0.1 → imas_python-2.1.0}/imas/setup_logging.py +0 -0
  177. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_all_dd_versions.py +0 -0
  178. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_dd_zip.py +0 -0
  179. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_deepcopy.py +0 -0
  180. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_exception.py +0 -0
  181. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_get_sample.py +0 -0
  182. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_hash.py +0 -0
  183. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids2nc.py +0 -0
  184. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_ascii_data.py +0 -0
  185. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_coordinates.py +0 -0
  186. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_data_type.py +0 -0
  187. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_factory.py +0 -0
  188. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_metadata.py +0 -0
  189. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_mixin.py +0 -0
  190. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_path.py +0 -0
  191. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_primitive.py +0 -0
  192. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_struct_array.py +0 -0
  193. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_structure.py +0 -0
  194. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_toplevel.py +0 -0
  195. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_ids_validate.py +0 -0
  196. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_latest_dd_autofill.py +0 -0
  197. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_latest_dd_manual.py +0 -0
  198. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_latest_dd_resample.py +0 -0
  199. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_list_occurrences.py +0 -0
  200. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal.py +0 -0
  201. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_conversion.py +0 -0
  202. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_io.py +0 -0
  203. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_struct_array_io.py +0 -0
  204. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_types.py +0 -0
  205. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_types_io.py +0 -0
  206. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_minimal_types_io_automatic.py +0 -0
  207. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_nbc_change.py +0 -0
  208. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_nc_autofill.py +0 -0
  209. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_nc_entry.py +0 -0
  210. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_nc_metadata.py +0 -0
  211. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_nc_validation.py +0 -0
  212. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_snippets.py +0 -0
  213. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_static_ids.py +0 -0
  214. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_str_1d.py +0 -0
  215. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_to_xarray.py +0 -0
  216. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_uda_support.py +0 -0
  217. {imas_python-2.0.1 → imas_python-2.1.0}/imas/test/test_util.py +0 -0
  218. {imas_python-2.0.1 → imas_python-2.1.0}/imas/util.py +0 -0
  219. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/dependency_links.txt +0 -0
  220. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/entry_points.txt +0 -0
  221. {imas_python-2.0.1 → imas_python-2.1.0}/imas_python.egg-info/top_level.txt +0 -0
  222. {imas_python-2.0.1 → imas_python-2.1.0}/setup.cfg +0 -0
  223. {imas_python-2.0.1 → imas_python-2.1.0}/tools/compare_lowlevel_access_patterns.py +0 -0
  224. {imas_python-2.0.1 → imas_python-2.1.0}/tools/extract_test_data.py +0 -0
  225. {imas_python-2.0.1 → imas_python-2.1.0}/tools/get_tagnames.py +0 -0
@@ -7,10 +7,10 @@ on:
7
7
 
8
8
  jobs:
9
9
  test:
10
- runs-on: ubuntu-22.04
10
+ runs-on: ubuntu-latest
11
11
  strategy:
12
12
  matrix:
13
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] # Test on multiple Python versions
13
+ python-version: ["3.10", "3.11", "3.12", "3.13"] # Test on multiple Python versions
14
14
 
15
15
  steps:
16
16
  - name: Checkout repository
@@ -20,8 +20,6 @@ jobs:
20
20
 
21
21
  uses: actions/setup-python@v4
22
22
  with:
23
- # until saxonche is available in 3.13
24
- # https://saxonica.plan.io/issues/6561
25
23
  python-version: ${{ matrix.python-version }}
26
24
  - name: Display Python version
27
25
  run: python -c "import sys; print(sys.version)"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imas-python
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: Pythonic wrappers for the IMAS Access Layer
5
5
  Author: ITER Organization
6
6
  Author-email: Karel Lucas van de Plassche <karelvandeplassche@gmail.com>, Daan van Vugt <dvanvugt@ignitioncomputing.com>, Maarten Sebregts <msebregts@ignitioncomputing.com>, imas-support@iter.org
@@ -213,6 +213,7 @@ Requires-Dist: importlib_resources; python_version < "3.9"
213
213
  Requires-Dist: packaging
214
214
  Requires-Dist: xxhash>=2
215
215
  Requires-Dist: imas_data_dictionaries
216
+ Requires-Dist: imas_core
216
217
  Provides-Extra: all
217
218
  Requires-Dist: imas-python[docs,test]; extra == "all"
218
219
  Provides-Extra: docs
@@ -10,8 +10,6 @@ from .utils import (
10
10
  available_serializers,
11
11
  available_slicing_backends,
12
12
  create_dbentry,
13
- factory,
14
- hlis,
15
13
  )
16
14
 
17
15
  N_SLICES = 32
@@ -26,13 +24,13 @@ def fill_slices(core_profiles, times):
26
24
  times: time values to fill a slice for
27
25
  """
28
26
  core_profiles.ids_properties.homogeneous_time = 1 # HOMOGENEOUS
29
- core_profiles.ids_properties.comment = "Generated for the IMAS-Python benchmark suite"
27
+ core_profiles.ids_properties.comment = (
28
+ "Generated for the IMAS-Python benchmark suite"
29
+ )
30
30
  core_profiles.ids_properties.creation_date = datetime.date.today().isoformat()
31
31
  core_profiles.code.name = "IMAS-Python ASV benchmark"
32
32
  core_profiles.code.version = imas.__version__
33
- core_profiles.code.repository = (
34
- "https://github.com/iterorganization/IMAS-Python"
35
- )
33
+ core_profiles.code.repository = "https://github.com/iterorganization/IMAS-Python"
36
34
 
37
35
  core_profiles.time = np.array(times)
38
36
  core_profiles.profiles_1d.resize(len(times))
@@ -50,13 +48,13 @@ def fill_slices(core_profiles, times):
50
48
  profiles_1d.ion.resize(len(ions))
51
49
  profiles_1d.neutral.resize(len(ions))
52
50
  for i, ion in enumerate(ions):
53
- if hasattr(profiles_1d.ion[i], 'label'):
51
+ if hasattr(profiles_1d.ion[i], "label"):
54
52
  profiles_1d.ion[i].label = ion
55
53
  profiles_1d.neutral[i].label = ion
56
- if hasattr(profiles_1d.ion[i], 'name'):
54
+ if hasattr(profiles_1d.ion[i], "name"):
57
55
  profiles_1d.ion[i].name = ion
58
56
  profiles_1d.neutral[i].name = ion
59
-
57
+
60
58
  # profiles_1d.ion[i].label = profiles_1d.neutral[i].label = ion
61
59
  profiles_1d.ion[i].z_ion = 1.0
62
60
  profiles_1d.ion[i].neutral_index = profiles_1d.neutral[i].ion_index = i + 1
@@ -70,31 +68,31 @@ def fill_slices(core_profiles, times):
70
68
 
71
69
 
72
70
  class GetSlice:
73
- params = [hlis, available_slicing_backends]
74
- param_names = ["hli", "backend"]
71
+ params = [available_slicing_backends]
72
+ param_names = ["backend"]
75
73
 
76
- def setup(self, hli, backend):
77
- self.dbentry = create_dbentry(hli, backend)
78
- core_profiles = factory[hli].core_profiles()
74
+ def setup(self, backend):
75
+ self.dbentry = create_dbentry(backend)
76
+ core_profiles = imas.IDSFactory().core_profiles()
79
77
  fill_slices(core_profiles, TIME)
80
78
  self.dbentry.put(core_profiles)
81
79
 
82
- def time_get_slice(self, hli, backend):
80
+ def time_get_slice(self, backend):
83
81
  for t in TIME:
84
82
  self.dbentry.get_slice("core_profiles", t, imas.ids_defs.CLOSEST_INTERP)
85
83
 
86
- def teardown(self, hli, backend):
84
+ def teardown(self, backend):
87
85
  if hasattr(self, "dbentry"): # imas + netCDF has no dbentry
88
86
  self.dbentry.close()
89
87
 
90
88
 
91
89
  class Get:
92
- params = [hlis, available_backends]
93
- param_names = ["hli", "backend"]
90
+ params = [available_backends]
91
+ param_names = ["backend"]
94
92
  setup = GetSlice.setup
95
93
  teardown = GetSlice.teardown
96
94
 
97
- def time_get(self, hli, backend):
95
+ def time_get(self, backend):
98
96
  self.dbentry.get("core_profiles")
99
97
 
100
98
 
@@ -103,8 +101,8 @@ class LazyGet:
103
101
  param_names = ["lazy", "backend"]
104
102
 
105
103
  def setup(self, lazy, backend):
106
- self.dbentry = create_dbentry("imas", backend)
107
- core_profiles = factory["imas"].core_profiles()
104
+ self.dbentry = create_dbentry(backend)
105
+ core_profiles = imas.IDSFactory().core_profiles()
108
106
  fill_slices(core_profiles, TIME)
109
107
  self.dbentry.put(core_profiles)
110
108
 
@@ -118,75 +116,72 @@ class LazyGet:
118
116
 
119
117
 
120
118
  class Generate:
121
- params = [hlis]
122
- param_names = ["hli"]
119
+ def setup(self):
120
+ self.core_profiles = imas.IDSFactory().core_profiles()
123
121
 
124
- def setup(self, hli):
125
- self.core_profiles = factory[hli].core_profiles()
126
-
127
- def time_generate(self, hli):
122
+ def time_generate(self):
128
123
  fill_slices(self.core_profiles, TIME)
129
124
 
130
- def time_generate_slices(self, hli):
125
+ def time_generate_slices(self):
131
126
  for t in TIME:
132
127
  fill_slices(self.core_profiles, [t])
133
128
 
134
- def time_create_core_profiles(self, hli):
135
- factory[hli].core_profiles()
129
+ def time_create_core_profiles(self):
130
+ imas.IDSFactory().core_profiles()
136
131
 
137
132
 
138
133
  class Put:
139
- params = [["0", "1"], hlis, available_backends]
134
+ params = [["0", "1"], available_backends]
140
135
  param_names = ["disable_validate", "hli", "backend"]
141
136
 
142
- def setup(self, disable_validate, hli, backend):
143
- create_dbentry(hli, backend).close() # catch unsupported combinations
144
- self.core_profiles = factory[hli].core_profiles()
137
+ def setup(self, disable_validate, backend):
138
+ create_dbentry(backend).close() # catch unsupported combinations
139
+ self.core_profiles = imas.IDSFactory().core_profiles()
145
140
  fill_slices(self.core_profiles, TIME)
146
141
  os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
147
142
 
148
- def time_put(self, disable_validate, hli, backend):
149
- with create_dbentry(hli, backend) as dbentry:
143
+ def time_put(self, disable_validate, backend):
144
+ with create_dbentry(backend) as dbentry:
150
145
  dbentry.put(self.core_profiles)
151
146
 
152
147
 
153
148
  class PutSlice:
154
- params = [["0", "1"], hlis, available_slicing_backends]
155
- param_names = ["disable_validate", "hli", "backend"]
149
+ params = [["0", "1"], available_slicing_backends]
150
+ param_names = ["disable_validate", "backend"]
156
151
 
157
- def setup(self, disable_validate, hli, backend):
158
- create_dbentry(hli, backend).close() # catch unsupported combinations
159
- self.core_profiles = factory[hli].core_profiles()
152
+ def setup(self, disable_validate, backend):
153
+ create_dbentry(backend).close() # catch unsupported combinations
154
+ self.core_profiles = imas.IDSFactory().core_profiles()
160
155
  os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
161
156
 
162
- def time_put_slice(self, disable_validate, hli, backend):
163
- with create_dbentry(hli, backend) as dbentry:
157
+ def time_put_slice(self, disable_validate, backend):
158
+ with create_dbentry(backend) as dbentry:
164
159
  for t in TIME:
165
160
  fill_slices(self.core_profiles, [t])
166
161
  dbentry.put_slice(self.core_profiles)
167
162
 
168
163
 
169
164
  class Serialize:
170
- params = [hlis, available_serializers]
171
- param_names = ["hli", "serializer"]
165
+ params = [available_serializers]
166
+ param_names = ["serializer"]
172
167
 
173
- def setup(self, hli, serializer):
174
- self.core_profiles = factory[hli].core_profiles()
168
+ def setup(self, serializer):
169
+ self.core_profiles = imas.IDSFactory().core_profiles()
175
170
  fill_slices(self.core_profiles, TIME)
176
171
 
177
- def time_serialize(self, hli, serializer):
172
+ def time_serialize(self, serializer):
178
173
  self.core_profiles.serialize(serializer)
179
174
 
180
175
 
181
176
  class Deserialize:
182
- params = [hlis, available_serializers]
183
- param_names = ["hli", "serializer"]
177
+ params = [available_serializers]
178
+ param_names = ["serializer"]
184
179
 
185
- def setup(self, hli, serializer):
186
- self.core_profiles = factory[hli].core_profiles()
180
+ def setup(self, serializer):
181
+ self.core_profiles = imas.IDSFactory().core_profiles()
187
182
  fill_slices(self.core_profiles, TIME)
188
183
  self.data = self.core_profiles.serialize(serializer)
189
- self.core_profiles = factory[hli].core_profiles()
184
+ self.core_profiles = imas.IDSFactory().core_profiles()
190
185
 
191
- def time_deserialize(self, hli, serializer):
186
+ def time_deserialize(self, serializer):
192
187
  self.core_profiles.deserialize(self.data)
@@ -5,7 +5,7 @@ import numpy as np
5
5
 
6
6
  import imas
7
7
 
8
- from .utils import available_backends, create_dbentry, factory, hlis
8
+ from .utils import available_backends, create_dbentry
9
9
 
10
10
  N_POINTS = 600 # number of random R,Z points
11
11
  N_LINES = 1200 # number of random lines in R,Z plane
@@ -27,9 +27,7 @@ def fill_ggd(edge_profiles, times):
27
27
  edge_profiles.ids_properties.creation_date = datetime.date.today().isoformat()
28
28
  edge_profiles.code.name = "IMAS-Python ASV benchmark"
29
29
  edge_profiles.code.version = imas.__version__
30
- edge_profiles.code.repository = (
31
- "https://github.com/iterorganization/IMAS-Python"
32
- )
30
+ edge_profiles.code.repository = "https://github.com/iterorganization/IMAS-Python"
33
31
 
34
32
  # This GGD grid is not a valid description, but it's a good stress test for the
35
33
  # typical access patterns that exist in GGD grids
@@ -124,45 +122,42 @@ def fill_ggd(edge_profiles, times):
124
122
 
125
123
 
126
124
  class Get:
127
- params = [hlis, available_backends]
128
- param_names = ["hli", "backend"]
125
+ params = [available_backends]
126
+ param_names = ["backend"]
129
127
 
130
- def setup(self, hli, backend):
131
- self.dbentry = create_dbentry(hli, backend)
132
- edge_profiles = factory[hli].edge_profiles()
128
+ def setup(self, backend):
129
+ self.dbentry = create_dbentry(backend)
130
+ edge_profiles = imas.IDSFactory().edge_profiles()
133
131
  fill_ggd(edge_profiles, TIME)
134
132
  self.dbentry.put(edge_profiles)
135
133
 
136
- def time_get(self, hli, backend):
134
+ def time_get(self, backend):
137
135
  self.dbentry.get("edge_profiles")
138
136
 
139
- def teardown(self, hli, backend):
137
+ def teardown(self, backend):
140
138
  if hasattr(self, "dbentry"): # imas + netCDF has no dbentry
141
139
  self.dbentry.close()
142
140
 
143
141
 
144
142
  class Generate:
145
- params = [hlis]
146
- param_names = ["hli"]
147
-
148
- def time_generate(self, hli):
149
- edge_profiles = factory[hli].edge_profiles()
143
+ def time_generate(self):
144
+ edge_profiles = imas.IDSFactory().edge_profiles()
150
145
  fill_ggd(edge_profiles, TIME)
151
146
 
152
- def time_create_edge_profiles(self, hli):
153
- factory[hli].edge_profiles()
147
+ def time_create_edge_profiles(self):
148
+ imas.IDSFactory().edge_profiles()
154
149
 
155
150
 
156
151
  class Put:
157
- params = [["0", "1"], hlis, available_backends]
158
- param_names = ["disable_validate", "hli", "backend"]
152
+ params = [["0", "1"], available_backends]
153
+ param_names = ["disable_validate", "backend"]
159
154
 
160
- def setup(self, disable_validate, hli, backend):
161
- create_dbentry(hli, backend).close() # catch unsupported combinations
162
- self.edge_profiles = factory[hli].edge_profiles()
155
+ def setup(self, disable_validate, backend):
156
+ create_dbentry(backend).close() # catch unsupported combinations
157
+ self.edge_profiles = imas.IDSFactory().edge_profiles()
163
158
  fill_ggd(self.edge_profiles, TIME)
164
159
  os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
165
160
 
166
- def time_put(self, disable_validate, hli, backend):
167
- with create_dbentry(hli, backend) as dbentry:
161
+ def time_put(self, disable_validate, backend):
162
+ with create_dbentry(backend) as dbentry:
168
163
  dbentry.put(self.edge_profiles)
@@ -1,10 +1,10 @@
1
- import importlib
2
1
  import logging
3
2
  import uuid
4
3
  from pathlib import Path
5
4
 
6
5
  import imas
7
6
  import imas.exception
7
+ import imas.ids_defs
8
8
 
9
9
  # Backend constants
10
10
  HDF5 = "HDF5"
@@ -56,28 +56,12 @@ available_slicing_backends = [
56
56
  backend for backend in available_backends if backend not in [ASCII, NETCDF]
57
57
  ]
58
58
 
59
- hlis = ["imas"]
60
- DBEntry = {
61
- "imas": imas.DBEntry,
62
- }
63
- factory = {
64
- "imas": imas.IDSFactory(),
65
- }
66
- available_serializers = [imas.ids_defs.ASCII_SERIALIZER_PROTOCOL]
67
-
59
+ available_serializers = [
60
+ imas.ids_defs.ASCII_SERIALIZER_PROTOCOL,
61
+ imas.ids_defs.FLEXBUFFERS_SERIALIZER_PROTOCOL,
62
+ ]
68
63
 
69
- def create_dbentry(hli, backend):
70
- if backend == NETCDF:
71
- if hli == "imas": # check if netcdf backend is available
72
- try:
73
- assert (
74
- imas.DBEntry._select_implementation("x.nc").__name__
75
- == "NCDBEntryImpl"
76
- )
77
- except (AttributeError, AssertionError):
78
- raise NotImplementedError(
79
- "This version of IMAS-Python doesn't implement netCDF."
80
- ) from None
81
64
 
82
- path = Path.cwd() / f"DB-{hli}-{backend}"
83
- return DBEntry[hli](create_uri(backend, path), "w")
65
+ def create_dbentry(backend):
66
+ path = Path.cwd() / f"DB-{backend}"
67
+ return imas.DBEntry(create_uri(backend, path), "w")
@@ -70,6 +70,13 @@ _BACKENDS = {
70
70
  "hdf5": HDF5_BACKEND,
71
71
  "mdsplus": MDSPLUS_BACKEND,
72
72
  }
73
+ try:
74
+ from imas.db_entry import DBEntry
75
+ from imas_core.exception import ImasCoreBackendException
76
+ DBEntry("imas:mdsplus?path=dummy","r")
77
+ except ImasCoreBackendException as iex:
78
+ if "not available" in str(iex.message):
79
+ _BACKENDS.pop("mdsplus")
73
80
 
74
81
 
75
82
  try:
@@ -3,6 +3,44 @@
3
3
  Changelog
4
4
  =========
5
5
 
6
+ What's new in IMAS-Python 2.1.0
7
+ -------------------------------
8
+
9
+ Build
10
+ '''''
11
+
12
+ - update Python version support (remove 3.8, add 3.13)
13
+ - add dependency on `imas_core <https://pypi.org/project/imas-core/>`__
14
+
15
+
16
+ Improvements
17
+ ''''''''''''
18
+
19
+ - :issue:`84`: improve `imas process-db-analysis`
20
+ - :issue:`71`: take into account identifier aliases (introduced in DD 4.1)
21
+ - :issue:`78`: disable *implicit* conversion when crossing a major version update
22
+ - improve integration of UDA backend
23
+ - cleaning old AL4 deprecated code
24
+ - :issue:`59`: convert name+identifier (DD3) into description+name (DD4)
25
+ - improve type hints (following PEP-585 and PEP-604)
26
+ - improve performance of IDS deepcopy
27
+ - :issue:`60`: improve `equilibrium` DD3->4 by converting `boundary_separatrix` into `contour_tree`
28
+ - :issue:`22`: add custom conversion example in the doc for `em_coupling` IDS
29
+
30
+
31
+ Bug fixes
32
+ '''''''''
33
+
34
+ - fix testcases with coordinate validation issues
35
+ - :issue:`80`: fix `imas print` when using netcdf and imas_core is not present
36
+ - :issue:`61`: special DD3->4 rule to flip sign quantities missing the `cocos_label_transform attribute` in DD
37
+ - :merge:`58`: fix unclear provenance capture
38
+ - :merge:`57`: fix 0D arrays from lazy loading with netcdf
39
+ - :issue:`55`: handle missing case when converting 3.42->4 (_tor->_phi)
40
+
41
+
42
+
43
+
6
44
  What's new in IMAS-Python 2.0.1
7
45
  -------------------------------
8
46
 
@@ -74,9 +112,9 @@ Bug fixes
74
112
  Dictionary 4.0.0 and 3.42.0. In other cases, the Data Dictionary version is
75
113
  now explicitly indicated.
76
114
 
77
- - :issue:`IMAS-5560`: Fix a bug where IMASPy would not correctly recognize that
115
+ - IMAS-5560: Fix a bug where IMASPy would not correctly recognize that
78
116
  the UDA backend is used.
79
- - :issue:`IMAS-5541`: Fix a bug when converting a closed contour to Data
117
+ - IMAS-5541: Fix a bug when converting a closed contour to Data
80
118
  Dictionary version 4.0.0.
81
119
  - Work around incorrect Data Dictionary 3.x metadata when converting
82
120
  ``flux_loop/flux`` in the ``magnetics`` IDS to Data Dictionary version 4.0.0.
@@ -121,8 +121,8 @@ process these files with ``imas process-db-analysis``. This will:
121
121
  variable).
122
122
  2. These results are summarized in a table, showing per IDS:
123
123
 
124
- - The number of data fields [#data_fields]_ that were filled in *any* of the
125
- analyzed data entries.
124
+ - The number of data fields [#data_fields]_ that were filled in *any* occurrence of
125
+ the IDS in *any* of the analyzed data entries.
126
126
  - The total number of data fields [#data_fields]_ that the Data Dictionary
127
127
  defines for this IDS.
128
128
  - The percentage of fields filled.
@@ -39,12 +39,12 @@ src_host = "https://github.com/iterorganization/"
39
39
  iter_projects = "https://github.com/iterorganization/"
40
40
  dd_url = urljoin(iter_projects, "imas-data-dictionary/")
41
41
  al_url = urljoin(iter_projects, "imas-core/")
42
- issue_url = jira_url = "https://github.com/iterorganization/IMAS-Python/issues"
43
42
 
44
43
  # IMAS-Python
45
44
  repository_url = f"{iter_projects}/{src_project}/"
46
45
  blob_url = repository_url
47
- mr_url = urljoin(repository_url, "/pulls")
46
+ issue_url = urljoin(repository_url, "issues/")
47
+ mr_url = urljoin(repository_url, "pull/")
48
48
 
49
49
 
50
50
  # Configuration of sphinx.ext.extlinks
@@ -52,8 +52,8 @@ mr_url = urljoin(repository_url, "/pulls")
52
52
  # unique name: (base URL, label prefix)
53
53
  extlinks = {
54
54
  "src": (blob_url + "%s", "%s"),
55
- "issue": (issue_url + "%s", "%s"),
56
- "merge": (mr_url + "%s", "!%s"),
55
+ "issue": (issue_url + "%s", "#%s"),
56
+ "merge": (mr_url + "%s", "#%s"),
57
57
  "dd": (dd_url + "%s", "%s"),
58
58
  "al": (al_url + "%s", "%s"),
59
59
  "pypa": ("https://packaging.python.org/%s", None),
@@ -25,15 +25,10 @@ can use the data.
25
25
  .. hint::
26
26
  Use the ASCII data supplied with IMAS-Python for all exercises. It contains two
27
27
  IDSs (``equilibrium`` and ``core_profiles``) filled with data from three
28
- time slices of ITER reference data. Two convenience methods are available in the
29
- :mod:`imas.training` module to open the DBEntry for this training data.
30
-
31
- 1. :meth:`imas.training.get_training_db_entry()` returns an opened
32
- ``imas.DBEntry`` object. Use this method if you want to use the IMAS-Python
33
- interface.
34
- 2. :meth:`imas.training.get_training_imas_db_entry()` returns an opened
35
- ``imas.DBEntry`` object. Use this method if you want to use the Python Access
36
- Layer interface.
28
+ time slices of ITER reference data. A convenience method is available in the
29
+ :mod:`imas.training` module to open the DBEntry for this training data:
30
+ :meth:`imas.training.get_training_db_entry()` returns an opened
31
+ ``imas.DBEntry`` object.
37
32
 
38
33
  Exercise 1
39
34
  ''''''''''
@@ -0,0 +1,168 @@
1
+ """IMAS-Python example for custom conversion logic.
2
+
3
+ This example script loads a Data Entry (in Data Dictionary 3.38.1) created by
4
+ DINA and converts the em_coupling IDS to DD 4.0.0.
5
+ """
6
+
7
+ import imas
8
+ from imas.ids_defs import IDS_TIME_MODE_INDEPENDENT
9
+
10
+ input_uri = "imas:hdf5?path=/work/imas/shared/imasdb/ITER_SCENARIOS/3/105013/1"
11
+ # An error is reported when there's already data at the output_uri!
12
+ output_uri = "imas:hdf5?path=105013-1-converted"
13
+ target_dd_version = "4.0.0"
14
+
15
+
16
+ # Mapping of DD 3.38.1 em_coupling data to DD 4.0.0
17
+ # Map the name of the matrix in DD 3.38.1 to the identifier and coordinate URIs
18
+ COUPLING_MAPS = {
19
+ "field_probes_active": dict(
20
+ coupling_quantity=2,
21
+ rows_uri="#magnetics/b_field_pol_probe",
22
+ columns_uri="#pf_active/coil",
23
+ ),
24
+ "field_probes_grid": dict(
25
+ coupling_quantity=2,
26
+ rows_uri="#magnetics/b_field_pol_probe",
27
+ columns_uri="#pf_plasma/element",
28
+ ),
29
+ "field_probes_passive": dict(
30
+ coupling_quantity=2,
31
+ rows_uri="#magnetics/b_field_pol_probe",
32
+ columns_uri="#pf_passive/loop",
33
+ ),
34
+ "mutual_active_active": dict(
35
+ coupling_quantity=1,
36
+ rows_uri="#pf_active/coil",
37
+ columns_uri="#pf_active/coil",
38
+ ),
39
+ "mutual_grid_active": dict(
40
+ coupling_quantity=1,
41
+ rows_uri="#pf_plasma/element",
42
+ columns_uri="#pf_active/coil",
43
+ ),
44
+ "mutual_grid_grid": dict(
45
+ coupling_quantity=1,
46
+ rows_uri="#pf_plasma/element",
47
+ columns_uri="#pf_plasma/element",
48
+ ),
49
+ "mutual_grid_passive": dict(
50
+ coupling_quantity=1,
51
+ rows_uri="#pf_plasma/element",
52
+ columns_uri="#pf_passive/loop",
53
+ ),
54
+ "mutual_loops_active": dict(
55
+ coupling_quantity=1,
56
+ rows_uri="#magnetics/flux_loop",
57
+ columns_uri="#pf_active/coil",
58
+ ),
59
+ "mutual_loops_passive": dict(
60
+ coupling_quantity=1,
61
+ rows_uri="#magnetics/flux_loop",
62
+ columns_uri="#pf_passive/loop",
63
+ ),
64
+ "mutual_loops_grid": dict(
65
+ coupling_quantity=1,
66
+ rows_uri="#magnetics/flux_loop",
67
+ columns_uri="#pf_plasma/element",
68
+ ),
69
+ "mutual_passive_active": dict(
70
+ coupling_quantity=1,
71
+ rows_uri="#pf_passive/loop",
72
+ columns_uri="#pf_active/coil",
73
+ ),
74
+ "mutual_passive_passive": dict(
75
+ coupling_quantity=1,
76
+ rows_uri="#pf_passive/loop",
77
+ columns_uri="#pf_passive/loop",
78
+ ),
79
+ }
80
+
81
+
82
+ with (
83
+ imas.DBEntry(input_uri, "r") as entry,
84
+ imas.DBEntry(output_uri, "x", dd_version=target_dd_version) as out,
85
+ ):
86
+ print("Loaded IMAS Data Entry:", input_uri)
87
+
88
+ print("This data entry contains the following IDSs:")
89
+ filled_idss = []
90
+ for idsname in entry.factory.ids_names():
91
+ occurrences = entry.list_all_occurrences(idsname)
92
+ if occurrences:
93
+ filled_idss.append(idsname)
94
+ print(f"- {idsname}, occurrences: {occurrences}")
95
+ print("")
96
+
97
+ # Load and convert all IDSs (except em_coupling) with imas.convert_ids()
98
+ # N.B. we know that the input URI doesn't have multiple occurrences, so
99
+ # we do not need to worry about them:
100
+ for idsname in filled_idss:
101
+ if idsname == "em_coupling":
102
+ continue
103
+
104
+ print(f"Loading IDS: {idsname}...")
105
+ ids = entry.get(idsname, autoconvert=False)
106
+ print(f"Converting IDS {idsname} to DD {target_dd_version}...")
107
+ ids4 = imas.convert_ids(
108
+ ids,
109
+ target_dd_version,
110
+ provenance_origin_uri=input_uri,
111
+ )
112
+ print(f"Storing IDS {idsname} to output data entry...")
113
+ out.put(ids4)
114
+
115
+ print("Conversion for em_coupling:")
116
+ emc = entry.get("em_coupling", autoconvert=False)
117
+ print("Using standard convert, this may log warnings about discarding data")
118
+ emc4 = imas.convert_ids(
119
+ emc,
120
+ target_dd_version,
121
+ provenance_origin_uri=input_uri,
122
+ )
123
+
124
+ print("Starting custom conversion of the coupling matrices")
125
+ for matrix_name, mapping in COUPLING_MAPS.items():
126
+ # Skip empty matrices
127
+ if not emc[matrix_name].has_value:
128
+ continue
129
+
130
+ # Allocate a new coupling_matrix AoS element
131
+ emc4.coupling_matrix.resize(len(emc4.coupling_matrix) + 1, keep=True)
132
+ # And fill it
133
+
134
+ emc4.coupling_matrix[-1].name = matrix_name
135
+ # Assigning an integer to the identifier will automatically fill the
136
+ # index/name/description. See documentation:
137
+ # https://imas-python.readthedocs.io/en/latest/identifiers.html
138
+ emc4.coupling_matrix[-1].quantity = mapping["coupling_quantity"]
139
+ emc4.coupling_matrix[-1].rows_uri = [mapping["rows_uri"]]
140
+ emc4.coupling_matrix[-1].columns_uri = [mapping["columns_uri"]]
141
+ emc4.coupling_matrix[-1].data = emc[matrix_name].value
142
+ # N.B. the original data has no error_upper/error_lower so we skip these
143
+ # Store em_coupling IDS
144
+ out.put(emc4)
145
+
146
+ print("Generating pf_plasma IDS...")
147
+ # N.B. This logic is specific to DINA
148
+ # Create a new pf_plasma IDS and set basic properties
149
+ pf_plasma = out.factory.pf_plasma()
150
+ pf_plasma.ids_properties.homogeneous_time = IDS_TIME_MODE_INDEPENDENT
151
+ pf_plasma.ids_properties.comment = "PF Plasma generated from equilibrium"
152
+
153
+ equilibrium = entry.get("equilibrium", lazy=True, autoconvert=False)
154
+ r = equilibrium.time_slice[0].profiles_2d[0].grid.dim1
155
+ z = equilibrium.time_slice[0].profiles_2d[0].grid.dim2
156
+ nr, nz = len(r), len(z)
157
+ # Generate a pf_plasma element for each grid point:
158
+ pf_plasma.element.resize(nr * nz)
159
+ for ir, rval in enumerate(r):
160
+ for iz, zval in enumerate(z):
161
+ element = pf_plasma.element[ir * nr + iz]
162
+ element.geometry.geometry_type = 2 # rectangle
163
+ element.geometry.rectangle.r = rval
164
+ element.geometry.rectangle.z = zval
165
+ # Store pf_plasma IDS
166
+ out.put(pf_plasma)
167
+
168
+ print("Conversion finished")