Repository: scalableminds/webknossos-libs

Issue:
dataset add_symlink_layer and add_copy_layer should have rename option
use case:
Dataset A has layer “color”, dataset B has another layer, also named “color”

I want to link A’s layer into dataset B, not currently possible because there is a name conflict
I would like to `b.add_symlink_layer(color_a_path, make_relative=True, rename_to="color_from_a")`

(should default to None, which takes the layer name from source dataset as is currently the case)

What do you think?


Discussion:

Resolving patch:
diff --git a/webknossos/webknossos/dataset/dataset.py b/webknossos/webknossos/dataset/dataset.py
--- a/webknossos/webknossos/dataset/dataset.py
+++ b/webknossos/webknossos/dataset/dataset.py
@@ -385,7 +385,10 @@ def delete_layer(self, layer_name: str) -> None:
         self._export_as_json()
 
     def add_symlink_layer(
-        self, foreign_layer: Union[str, Path, Layer], make_relative: bool = False
+        self,
+        foreign_layer: Union[str, Path, Layer],
+        make_relative: bool = False,
+        new_layer_name: str = None,
     ) -> Layer:
         """
         Creates a symlink to the data at `foreign_layer` which belongs to another dataset.
@@ -393,6 +396,7 @@ def add_symlink_layer(
         Note: If the other dataset modifies its bounding box afterwards, the change does not affect this properties
         (or vice versa).
         If make_relative is True, the symlink is made relative to the current dataset path.
+        If new_layer_name is None, the name of the foreign layer is used.
         """
 
         if isinstance(foreign_layer, Layer):
@@ -400,7 +404,10 @@ def add_symlink_layer(
         else:
             foreign_layer_path = Path(foreign_layer)
 
-        layer_name = foreign_layer_path.name
+        foreign_layer_name = foreign_layer_path.name
+        layer_name = (
+            new_layer_name if new_layer_name is not None else foreign_layer_name
+        )
         if layer_name in self.layers.keys():
             raise IndexError(
                 f"Cannot create symlink to {foreign_layer_path}. This dataset already has a layer called {layer_name}."
@@ -412,8 +419,11 @@ def add_symlink_layer(
             else Path(os.path.abspath(foreign_layer_path))
         )
         os.symlink(foreign_layer_symlink_path, join(self.path, layer_name))
-        original_layer = Dataset(foreign_layer_path.parent).get_layer(layer_name)
+        original_layer = Dataset(foreign_layer_path.parent).get_layer(
+            foreign_layer_name
+        )
         layer_properties = copy.deepcopy(original_layer._properties)
+        layer_properties.name = layer_name
         self._properties.data_layers += [layer_properties]
         self._layers[layer_name] = self._initialize_layer_from_properties(
             layer_properties
@@ -422,10 +432,13 @@ def add_symlink_layer(
         self._export_as_json()
         return self.layers[layer_name]
 
-    def add_copy_layer(self, foreign_layer: Union[str, Path, Layer]) -> Layer:
+    def add_copy_layer(
+        self, foreign_layer: Union[str, Path, Layer], new_layer_name: str = None
+    ) -> Layer:
         """
         Copies the data at `foreign_layer` which belongs to another dataset to the current dataset.
         Additionally, the relevant information from the `datasource-properties.json` of the other dataset are copied too.
+        If new_layer_name is None, the name of the foreign layer is used.
         """
 
         if isinstance(foreign_layer, Layer):
@@ -434,15 +447,21 @@ def add_copy_layer(self, foreign_layer: Union[str, Path, Layer]) -> Layer:
             foreign_layer_path = Path(foreign_layer)
 
         foreign_layer_path = Path(os.path.abspath(foreign_layer_path))
-        layer_name = foreign_layer_path.name
+        foreign_layer_name = foreign_layer_path.name
+        layer_name = (
+            new_layer_name if new_layer_name is not None else foreign_layer_name
+        )
         if layer_name in self.layers.keys():
             raise IndexError(
                 f"Cannot copy {foreign_layer_path}. This dataset already has a layer called {layer_name}."
             )
 
         shutil.copytree(foreign_layer_path, join(self.path, layer_name))
-        original_layer = Dataset(foreign_layer_path.parent).get_layer(layer_name)
+        original_layer = Dataset(foreign_layer_path.parent).get_layer(
+            foreign_layer_name
+        )
         layer_properties = copy.deepcopy(original_layer._properties)
+        layer_properties.name = layer_name
         self._properties.data_layers += [layer_properties]
         self._layers[layer_name] = self._initialize_layer_from_properties(
             layer_properties


Test patch: