Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 116 additions & 4 deletions imas/ids_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,18 @@ def add_rename(old_path: str, new_path: str):

def _apply_3to4_conversion(self, old: Element, new: Element) -> None:
# Postprocessing for COCOS definition change:
cocos_paths = []
for psi_like in ["psi_like", "dodpsi_like"]:
xpath_query = f".//field[@cocos_label_transformation='{psi_like}']"
for old_item in old.iterfind(xpath_query):
old_path = old_item.get("path")
new_path = self.old_to_new.path.get(old_path, old_path)
self.new_to_old.post_process[new_path] = _cocos_change
self.old_to_new.post_process[old_path] = _cocos_change
cocos_paths.append(old_item.get("path"))
# Sign flips not covered by the generic rule:
cocos_paths.extend(_3to4_sign_flip_paths.get(self.ids_name, []))
for old_path in cocos_paths:
new_path = self.old_to_new.path.get(old_path, old_path)
self.new_to_old.post_process[new_path] = _cocos_change
self.old_to_new.post_process[old_path] = _cocos_change

# Definition change for pf_active circuit/connections
if self.ids_name == "pf_active":
path = "circuit/connections"
Expand Down Expand Up @@ -676,6 +681,113 @@ def _copy_structure(
callback(item, target_item)


_3to4_sign_flip_paths = {
"core_instant_changes": [
"change/profiles_1d/grid/psi_magnetic_axis",
"change/profiles_1d/grid/psi_boundary",
],
"core_profiles": [
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
],
"core_sources": [
"source/profiles_1d/grid/psi_magnetic_axis",
"source/profiles_1d/grid/psi_boundary",
],
"core_transport": [
"model/profiles_1d/grid_d/psi_magnetic_axis",
"model/profiles_1d/grid_d/psi_boundary",
"model/profiles_1d/grid_v/psi_magnetic_axis",
"model/profiles_1d/grid_v/psi_boundary",
"model/profiles_1d/grid_flux/psi_magnetic_axis",
"model/profiles_1d/grid_flux/psi_boundary",
],
"disruption": [
"global_quantities/psi_halo_boundary",
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
],
"ece": [
"channel/beam_tracing/beam/position/psi",
"psi_normalization/psi_magnetic_axis",
"psi_normalization/psi_boundary",
],
"edge_profiles": [
"profiles_1d/grid/psi",
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
],
"equilibrium": [
"time_slice/boundary/psi",
"time_slice/global_quantities/q_min/psi",
"time_slice/ggd/psi/values",
],
"mhd": ["ggd/psi/values"],
"pellets": ["time_slice/pellet/path_profiles/psi"],
"plasma_profiles": [
"profiles_1d/grid/psi",
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
"ggd/psi/values",
],
"plasma_sources": [
"source/profiles_1d/grid/psi",
"source/profiles_1d/grid/psi_magnetic_axis",
"source/profiles_1d/grid/psi_boundary",
],
"plasma_transport": [
"model/profiles_1d/grid_d/psi",
"model/profiles_1d/grid_d/psi_magnetic_axis",
"model/profiles_1d/grid_d/psi_boundary",
"model/profiles_1d/grid_v/psi",
"model/profiles_1d/grid_v/psi_magnetic_axis",
"model/profiles_1d/grid_v/psi_boundary",
"model/profiles_1d/grid_flux/psi",
"model/profiles_1d/grid_flux/psi_magnetic_axis",
"model/profiles_1d/grid_flux/psi_boundary",
],
"radiation": [
"process/profiles_1d/grid/psi_magnetic_axis",
"process/profiles_1d/grid/psi_boundary",
],
"reflectometer_profile": [
"psi_normalization/psi_magnetic_axis",
"psi_normalization/psi_boundary",
],
"reflectometer_fluctuation": [
"psi_normalization/psi_magnetic_axis",
"psi_normalization/psi_boundary",
],
"runaway_electrons": [
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
],
"sawteeth": [
"profiles_1d/grid/psi_magnetic_axis",
"profiles_1d/grid/psi_boundary",
],
"summary": [
"global_quantities/psi_external_average/value",
"local/magnetic_axis/position/psi",
],
"transport_solver_numerics": [
"solver_1d/grid/psi_magnetic_axis",
"solver_1d/grid/psi_boundary",
"derivatives_1d/grid/psi_magnetic_axis",
"derivatives_1d/grid/psi_boundary",
],
"wall": ["description_ggd/ggd/psi/values"],
"waves": [
"coherent_wave/profiles_1d/grid/psi_magnetic_axis",
"coherent_wave/profiles_1d/grid/psi_boundary",
"coherent_wave/profiles_2d/grid/psi",
"coherent_wave/beam_tracing/beam/position/psi",
],
}
"""List of paths per IDS that require a COCOS sign change, but aren't covered by the
generic rule."""


########################################################################################
# Type changed handlers and post-processing functions #
########################################################################################
Expand Down
21 changes: 21 additions & 0 deletions imas/test/test_ids_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@

from imas import identifiers
from imas.ids_convert import (
_3to4_sign_flip_paths,
_get_ctxpath,
_get_tbp,
convert_ids,
dd_version_map_from_factories,
iter_parents,
)
from imas.ids_data_type import IDSDataType
from imas.ids_defs import (
ASCII_BACKEND,
IDS_TIME_MODE_HETEROGENEOUS,
Expand Down Expand Up @@ -529,3 +531,22 @@ def test_3to4_migrate_deprecated_fields(): # GH#55
del cp342.profiles_1d[0].ion[0].label
cp4 = convert_ids(cp342, "4.0.0")
assert cp4.profiles_1d[0].ion[0].name == "y"


def test_3to4_cocos_hardcoded_paths():
# Check for existence in 3.42.0
factory = IDSFactory("3.42.0")
for ids_name, paths in _3to4_sign_flip_paths.items():
ids = factory.new(ids_name)
for path in paths:
# Check path exists and is not a FLT
metadata = ids.metadata[path]
assert metadata.data_type is IDSDataType.FLT

# Test a conversion
eq = factory.equilibrium()
eq.time_slice.resize(1)
eq.time_slice[0].boundary.psi = 3.141

eq4 = convert_ids(eq, "4.0.0")
assert eq4.time_slice[0].boundary.psi == -3.141
Loading