@@ -2171,6 +2171,7 @@ def add_copy_layer(
21712171 chunks_per_shard : Optional [Union [Vec3IntLike , int ]] = None ,
21722172 data_format : Optional [Union [str , DataFormat ]] = None ,
21732173 compress : Optional [bool ] = None ,
2174+ exists_ok : bool = False ,
21742175 executor : Optional [Executor ] = None ,
21752176 ) -> Layer :
21762177 """Copy layer from another dataset to this one.
@@ -2186,6 +2187,7 @@ def add_copy_layer(
21862187 chunks_per_shard: Deprecated, use shard_shape. Optional number of chunks per shard
21872188 data_format: Optional format to store copied data ('wkw', 'zarr', etc.)
21882189 compress: Optional whether to compress copied data
2190+ exists_ok: Whether to overwrite existing layers
21892191 executor: Optional executor for parallel copying
21902192
21912193 Returns:
@@ -2217,30 +2219,46 @@ def add_copy_layer(
22172219 if new_layer_name is None :
22182220 new_layer_name = foreign_layer .name
22192221
2220- if new_layer_name in self .layers .keys ():
2221- raise IndexError (
2222- f"Cannot copy { foreign_layer } . This dataset already has a layer called { new_layer_name } ."
2222+ if exists_ok :
2223+ layer = self .get_or_add_layer (
2224+ new_layer_name ,
2225+ category = foreign_layer .category ,
2226+ dtype_per_channel = foreign_layer .dtype_per_channel ,
2227+ num_channels = foreign_layer .num_channels ,
2228+ data_format = data_format or foreign_layer .data_format ,
2229+ largest_segment_id = foreign_layer ._get_largest_segment_id_maybe (),
2230+ bounding_box = foreign_layer .bounding_box ,
2231+ )
2232+ else :
2233+ if new_layer_name in self .layers .keys ():
2234+ raise IndexError (
2235+ f"Cannot copy { foreign_layer } . This dataset already has a layer called { new_layer_name } ."
2236+ )
2237+ layer = self .add_layer (
2238+ new_layer_name ,
2239+ category = foreign_layer .category ,
2240+ dtype_per_channel = foreign_layer .dtype_per_channel ,
2241+ num_channels = foreign_layer .num_channels ,
2242+ data_format = data_format or foreign_layer .data_format ,
2243+ largest_segment_id = foreign_layer ._get_largest_segment_id_maybe (),
2244+ bounding_box = foreign_layer .bounding_box ,
22232245 )
2224-
2225- layer = self .add_layer (
2226- new_layer_name ,
2227- category = foreign_layer .category ,
2228- dtype_per_channel = foreign_layer .dtype_per_channel ,
2229- num_channels = foreign_layer .num_channels ,
2230- data_format = data_format or foreign_layer .data_format ,
2231- largest_segment_id = foreign_layer ._get_largest_segment_id_maybe (),
2232- )
2233- layer .bounding_box = foreign_layer .bounding_box
22342246
22352247 for mag_view in foreign_layer .mags .values ():
2248+ progress_desc = (
2249+ f"Copying { mag_view .layer .name } /{ mag_view .mag .to_layer_name ()} "
2250+ )
2251+
22362252 layer .add_copy_mag (
22372253 mag_view ,
22382254 extend_layer_bounding_box = False ,
22392255 chunk_shape = chunk_shape ,
22402256 shard_shape = shard_shape ,
22412257 chunks_per_shard = chunks_per_shard ,
22422258 compress = compress ,
2259+ exists_ok = exists_ok ,
22432260 executor = executor ,
2261+ progress_desc = progress_desc ,
22442262 )
22452263
22462264 return layer
@@ -2458,6 +2476,7 @@ def copy_dataset(
24582476 chunks_per_shard : Optional [Union [Vec3IntLike , int ]] = None ,
24592477 data_format : Optional [Union [str , DataFormat ]] = None ,
24602478 compress : Optional [bool ] = None ,
2479+ exists_ok : bool = False ,
24612480 executor : Optional [Executor ] = None ,
24622481 voxel_size_with_unit : Optional [VoxelSize ] = None ,
24632482 ) -> "Dataset" :
@@ -2473,6 +2492,7 @@ def copy_dataset(
24732492 chunks_per_shard: Deprecated, use shard_shape. Optional number of chunks per shard
24742493 data_format: Optional format to store data ('wkw', 'zarr', 'zarr3')
24752494 compress: Optional whether to compress data
2495+ exists_ok: Whether to overwrite existing datasets and layers
24762496 executor: Optional executor for parallel copying
24772497 voxel_size_with_unit: Optional voxel size specification with units
24782498
@@ -2507,13 +2527,13 @@ def copy_dataset(
25072527 if data_format == DataFormat .WKW :
25082528 assert is_fs_path (
25092529 new_dataset_path
2510- ), "Cannot create WKW-based remote datasets. Use `data_format='zarr '` instead."
2530+ ), "Cannot create WKW-based remote datasets. Use `data_format='zarr3 '` instead."
25112531 if data_format is None and any (
25122532 layer .data_format == DataFormat .WKW for layer in self .layers .values ()
25132533 ):
25142534 assert is_fs_path (
25152535 new_dataset_path
2516- ), "Cannot create WKW layers in remote datasets. Use explicit `data_format='zarr '`."
2536+ ), "Cannot create WKW layers in remote datasets. Use explicit `data_format='zarr3 '`."
25172537
25182538 if voxel_size_with_unit is None :
25192539 if voxel_size is None :
@@ -2523,7 +2543,7 @@ def copy_dataset(
25232543 new_ds = Dataset (
25242544 new_dataset_path ,
25252545 voxel_size_with_unit = voxel_size_with_unit ,
2526- exist_ok = False ,
2546+ exist_ok = exists_ok ,
25272547 )
25282548
25292549 with get_executor_for_args (None , executor ) as executor :
@@ -2535,6 +2555,7 @@ def copy_dataset(
25352555 chunks_per_shard = chunks_per_shard ,
25362556 data_format = data_format ,
25372557 compress = compress ,
2558+ exists_ok = exists_ok ,
25382559 executor = executor ,
25392560 )
25402561 new_ds ._export_as_json ()
0 commit comments