diff --git a/imas/ids_convert.py b/imas/ids_convert.py index a1707c1..ce6a129 100644 --- a/imas/ids_convert.py +++ b/imas/ids_convert.py @@ -456,6 +456,8 @@ def _apply_3to4_conversion(self, old: Element, new: Element) -> None: # Map DD3 name -> DD4 description if name_path not in self.old_to_new.path: self._add_rename(name_path, desc_path) + # GH#114: Also preserve name in DD4 name when identifier is empty + self.old_to_new.type_change[name_path] = _name_identifier_3to4 # Map DD3 identifier -> DD4 name if id_path in self.old_to_new.path: @@ -1154,6 +1156,19 @@ def _circuit_connections_4to3(node: IDSPrimitive) -> None: node.value = new_value +def _name_identifier_3to4(source_name: IDSBase, target_description: IDSBase) -> None: + """Preserve name when identifier is empty, see GH#114.""" + # Always copy DD3 name -> DD4 description + target_description.value = source_name.value + + # When DD3 identifier is empty, also preserve name in DD4 name + source_parent = source_name._parent + source_identifier = getattr(source_parent, "identifier", None) + if source_identifier is None or not source_identifier.value: + target_parent = target_description._parent + target_parent.name = source_name.value + + def _ids_properties_source(source: IDSString0D, provenance: IDSStructure) -> None: """Handle DD3to4 migration of ids_properties/source to ids_properties/provenance.""" if len(provenance.node) > 0: diff --git a/imas/test/test_ids_convert.py b/imas/test/test_ids_convert.py index b79fb1b..1c712b7 100644 --- a/imas/test/test_ids_convert.py +++ b/imas/test/test_ids_convert.py @@ -575,6 +575,29 @@ def test_4to3_name_identifier_mapping_magnetics(): assert dst.b_field_pol_probe[0].identifier == "TEST_NAME" +def test_3to4_name_identifier_empty_identifier(): + """GH#114: name must be preserved when identifier is empty.""" + factory = IDSFactory("3.40.1") + + src = factory.pf_active() + src.ids_properties.homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS + src.coil.resize(2) + # Case 1: name populated, identifier empty + src.coil[0].name = "TEST_NAME" + src.coil[0].identifier = "" + # Case 2: name populated, identifier not set at all + src.coil[1].name = "TEST_NAME2" + + dst = convert_ids(src, "4.0.0") + + # name must be preserved in DD4 name (not overwritten by empty identifier) + assert dst.coil[0].name == "TEST_NAME" + assert dst.coil[0].description == "TEST_NAME" + + assert dst.coil[1].name == "TEST_NAME2" + assert dst.coil[1].description == "TEST_NAME2" + + def test_3to4_cocos_hardcoded_paths(): # Check for existence in 3.42.0 factory = IDSFactory("3.42.0")