-
Notifications
You must be signed in to change notification settings - Fork 16
Convert core/edge to plasma IDS #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
olivhoenen
merged 6 commits into
iterorganization:develop
from
maarten-ic:feature/convert-core-edge-to-plasma-ids
Jan 16, 2026
+351
−26
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0aeeb22
Add conversion logic for core/edge -> plasma IDS
maarten-ic 1df6e82
Add docstrings for convert to plasma functions
maarten-ic 667dd62
Update __init__.py and docs
maarten-ic 2329227
Add option to `imas convert` CLI to convert core/edge to plasma IDSs
maarten-ic 2a3c973
Fix incorrect handling of core_instant_changes IDS in `imas convert -…
maarten-ic 6bbf866
Merge branch 'develop' into feature/convert-core-edge-to-plasma-ids
maarten-ic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,58 @@ | ||
| # This file is part of IMAS-Python. | ||
| # You should have received the IMAS-Python LICENSE file with this project. | ||
|
|
||
| # isort: skip_file | ||
|
|
||
| from packaging.version import Version as _V | ||
|
|
||
| from ._version import version as __version__ # noqa: F401 | ||
| from ._version import version_tuple # noqa: F401 | ||
|
|
||
| # Import logging _first_ | ||
| from . import setup_logging | ||
| # isort: off | ||
| from . import setup_logging # noqa: F401 | ||
|
|
||
| # isort: on | ||
|
|
||
| # Import main user API objects in the imas module | ||
| # Ensure that `imas.util` is loaded when importing imas | ||
| from . import util # noqa: F401 | ||
|
|
||
| # Public API: | ||
| from ._version import version as __version__ | ||
| from ._version import version_tuple | ||
| from .convert_core_edge_plasma import ( | ||
| convert_to_plasma_profiles, | ||
| convert_to_plasma_sources, | ||
| convert_to_plasma_transport, | ||
| ) | ||
| from .db_entry import DBEntry | ||
| from .ids_factory import IDSFactory | ||
| from .ids_convert import convert_ids | ||
| from .ids_data_type import IDSDataType | ||
| from .ids_factory import IDSFactory | ||
| from .ids_identifiers import identifiers | ||
|
|
||
| # Load the IMAS-Python IMAS AL/DD core | ||
| from . import ( | ||
| db_entry, | ||
| dd_zip, | ||
| util, | ||
| ) | ||
| from .ids_metadata import IDSMetadata, IDSType | ||
| from .ids_primitive import IDSPrimitive | ||
| from .ids_struct_array import IDSStructArray | ||
| from .ids_structure import IDSStructure | ||
| from .ids_toplevel import IDSToplevel | ||
|
|
||
| PUBLISHED_DOCUMENTATION_ROOT = "https://imas-python.readthedocs.io/en/latest/" | ||
| """URL to the published documentation.""" | ||
| OLDEST_SUPPORTED_VERSION = _V("3.22.0") | ||
| """Oldest Data Dictionary version that is supported by IMAS-Python.""" | ||
|
|
||
| __all__ = [ | ||
| "__version__", | ||
| "version_tuple", | ||
| "DBEntry", | ||
| "IDSDataType", | ||
| "IDSFactory", | ||
| "IDSMetadata", | ||
| "IDSPrimitive", | ||
| "IDSStructure", | ||
| "IDSStructArray", | ||
| "IDSToplevel", | ||
| "IDSType", | ||
| "convert_ids", | ||
| "convert_to_plasma_profiles", | ||
| "convert_to_plasma_sources", | ||
| "convert_to_plasma_transport", | ||
| "identifiers", | ||
| "PUBLISHED_DOCUMENTATION_ROOT", | ||
| "OLDEST_SUPPORTED_VERSION", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| # This file is part of IMAS-Python. | ||
| # You should have received the IMAS-Python LICENSE file with this project. | ||
| """Logic to convert core/edge IDSs to their corresponding plasma ID.""" | ||
|
|
||
| from packaging.version import Version | ||
|
|
||
| from imas.ids_toplevel import IDSToplevel | ||
| from imas.ids_factory import IDSFactory | ||
| from imas.exception import IDSNameError | ||
| from imas.ids_convert import DDVersionMap, NBCPathMap, _copy_structure | ||
|
|
||
|
|
||
| def convert_to_plasma_profiles( | ||
| core_or_edge_profiles: IDSToplevel, *, deepcopy: bool = False | ||
| ) -> IDSToplevel: | ||
| """Convert a core_profiles or edge_profiles IDS to a plasma_profiles IDS. | ||
|
|
||
| The input IDS must use a Data Dictionary version for which the plasma_profiles IDS | ||
| exists (3.42.0 or newer). | ||
|
|
||
| Args: | ||
| core_or_edge_profiles: The core_profiles or edge_profiles IDS to be converted. | ||
|
|
||
| Keyword Args: | ||
| deepcopy: When True, performs a deep copy of all data. When False (default), | ||
| numpy arrays are not copied and the converted IDS shares the same underlying | ||
| data buffers. | ||
| """ | ||
| return _convert_to_plasma(core_or_edge_profiles, "profiles", deepcopy) | ||
|
|
||
|
|
||
| def convert_to_plasma_sources( | ||
| core_or_edge_sources: IDSToplevel, *, deepcopy: bool = False | ||
| ) -> IDSToplevel: | ||
| """Convert a core_sources or edge_sources IDS to a plasma_sources IDS. | ||
|
|
||
| The input IDS must use a Data Dictionary version for which the plasma_sources IDS | ||
| exists (3.42.0 or newer). | ||
|
|
||
| Args: | ||
| core_or_edge_sources: The core_sources or edge_sources IDS to be converted. | ||
|
|
||
| Keyword Args: | ||
| deepcopy: When True, performs a deep copy of all data. When False (default), | ||
| numpy arrays are not copied and the converted IDS shares the same underlying | ||
| data buffers. | ||
| """ | ||
| return _convert_to_plasma(core_or_edge_sources, "sources", deepcopy) | ||
|
|
||
|
|
||
| def convert_to_plasma_transport( | ||
| core_or_edge_transport: IDSToplevel, *, deepcopy: bool = False | ||
| ) -> IDSToplevel: | ||
| """Convert a core_transport or edge_transport IDS to a plasma_transport IDS. | ||
|
|
||
| The input IDS must use a Data Dictionary version for which the plasma_transport IDS | ||
| exists (3.42.0 or newer). | ||
|
|
||
| Args: | ||
| core_or_edge_transport: The core_transport or edge_transport IDS to be | ||
| converted. | ||
|
|
||
| Keyword Args: | ||
| deepcopy: When True, performs a deep copy of all data. When False (default), | ||
| numpy arrays are not copied and the converted IDS shares the same underlying | ||
| data buffers. | ||
| """ | ||
| return _convert_to_plasma(core_or_edge_transport, "transport", deepcopy) | ||
|
|
||
|
|
||
| class _CoreEdgePlasmaMap(DDVersionMap): | ||
| """Subclass of DDVersionMap to generate an NBCPathMap that is suitable to copy | ||
| between a core/edge IDS and the corresponding plasma IDS.""" | ||
|
|
||
| def __init__(self, source, target, factory): | ||
| self.ids_name = source | ||
| self.old_version = factory._etree | ||
| self.new_version = factory._etree | ||
| self.version_old = Version(factory.version) | ||
|
|
||
| self.old_to_new = NBCPathMap() | ||
| self.new_to_old = NBCPathMap() | ||
|
|
||
| old_ids_object = factory._etree.find(f"IDS[@name='{source}']") | ||
| new_ids_object = factory._etree.find(f"IDS[@name='{target}']") | ||
| self._build_map(old_ids_object, new_ids_object) | ||
|
|
||
|
|
||
| def _convert_to_plasma(source: IDSToplevel, suffix: str, deepcopy: bool) -> IDSToplevel: | ||
| # Sanity checks for input data | ||
| if not isinstance(source, IDSToplevel): | ||
| raise TypeError( | ||
| f"First argument to convert_to_plasma_{suffix} must be a core_{suffix} or " | ||
| f"edge_{suffix} of type IDSToplevel. Got a type {type(source)} instead." | ||
| ) | ||
| if source.metadata.name not in [f"core_{suffix}", f"edge_{suffix}"]: | ||
| raise ValueError( | ||
| f"First argument to convert_to_plasma_{suffix} must be a core_{suffix} or " | ||
| f"edge_{suffix} IDS. Got a {source.metadata.name} IDS instead." | ||
| ) | ||
| if source._lazy: | ||
| raise NotImplementedError( | ||
| "IDS conversion is not implemented for lazy-loaded IDSs" | ||
| ) | ||
|
|
||
| # Construct target plasma_{suffix} IDS | ||
| factory: IDSFactory = source._parent | ||
| try: | ||
| target = factory.new(f"plasma_{suffix}") | ||
| except IDSNameError: | ||
| raise ValueError( | ||
| f"Cannot convert {source.metadata.name} IDS to plasma_{suffix}: the source " | ||
| f"IDS uses Data Dictionary version {factory.dd_version} which doesn't have " | ||
| f"a plasma_{suffix} IDS. Please convert the source IDS to a supported Data " | ||
| "Dictionary version using `imas.convert_ids` and try again." | ||
| ) from None | ||
|
|
||
| # Leverage existing logic from ids_convert to do the copying | ||
| # First construct a map (to handle missing items in the target IDS) | ||
| data_map = _CoreEdgePlasmaMap(source.metadata.name, target.metadata.name, factory) | ||
| path_map = data_map.old_to_new # old = core/edge, new = plasma IDS | ||
| _copy_structure(source, target, deepcopy, path_map) | ||
|
|
||
| return target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this test shall be improved, currently it will get also the
core_instant_changesIDS (still have to find a data-entry with such IDS).Otherwise it looks good to me, but I'm waiting an answer to iterorganization/IMAS-Data-Dictionary#191 before approving.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sharp, I didn't think of that indeed! I'll update the logic