Skip to content

Commit e794219

Browse files
authored
Support adding a layer via symlink (#240)
* support adding layers with symlinks * reformat code
1 parent e338375 commit e794219

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

tests/test_dataset.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import filecmp
22
import json
3+
import os
34
from os.path import dirname
45
import pytest
56

@@ -1276,3 +1277,31 @@ def test_view_offsets():
12761277
raise Exception(expected_error_msg)
12771278
except AssertionError:
12781279
pass
1280+
1281+
1282+
def test_add_symlink_layer():
1283+
delete_dir("./testoutput/wk_dataset_with_symlink")
1284+
delete_dir("./testoutput/simple_wk_dataset_copy")
1285+
copytree("./testdata/simple_wk_dataset/", "./testoutput/simple_wk_dataset_copy/")
1286+
1287+
original_mag = (
1288+
WKDataset("./testoutput/simple_wk_dataset_copy/")
1289+
.get_layer("color")
1290+
.get_mag("1")
1291+
)
1292+
1293+
ds = WKDataset.create("./testoutput/wk_dataset_with_symlink", scale=(1, 1, 1))
1294+
symlink_layer = ds.add_symlink_layer("./testoutput/simple_wk_dataset_copy/color/")
1295+
mag = symlink_layer.get_mag("1")
1296+
1297+
assert path.exists("./testoutput/wk_dataset_with_symlink/color/1")
1298+
1299+
assert len(ds.properties.data_layers) == 1
1300+
assert len(ds.properties.data_layers["color"].wkw_magnifications) == 1
1301+
1302+
# write data in symlink layer
1303+
write_data = (np.random.rand(3, 10, 10, 10) * 255).astype(np.uint8)
1304+
mag.write(write_data)
1305+
1306+
assert np.array_equal(mag.read((10, 10, 10)), write_data)
1307+
assert np.array_equal(original_mag.read((10, 10, 10)), write_data)

wkcuber/api/Dataset.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,32 @@ def delete_layer(self, layer_name):
129129
# delete files on disk
130130
rmtree(join(self.path, layer_name))
131131

132+
def add_symlink_layer(self, foreign_layer_path) -> Layer:
133+
foreign_layer_path = os.path.abspath(foreign_layer_path)
134+
layer_name = os.path.basename(os.path.normpath(foreign_layer_path))
135+
if layer_name in self.layers.keys():
136+
raise IndexError(
137+
f"Cannot create symlink to {foreign_layer_path}. This dataset already has a layer called {layer_name}."
138+
)
139+
140+
os.symlink(foreign_layer_path, join(self.path, layer_name))
141+
142+
# copy the properties of the layer into the properties of this dataset
143+
layer_properties = self._get_type()(
144+
Path(foreign_layer_path).parent
145+
).properties.data_layers[layer_name]
146+
self.properties.data_layers[layer_name] = layer_properties
147+
self.properties._export_as_json()
148+
149+
self.layers[layer_name] = self._create_layer(
150+
layer_name,
151+
np.dtype(layer_properties.element_class),
152+
layer_properties.num_channels,
153+
)
154+
for resolution in layer_properties.wkw_magnifications:
155+
self.layers[layer_name].setup_mag(resolution.mag.to_layer_name())
156+
return self.layers[layer_name]
157+
132158
def get_view(self, layer_name, mag, size, offset=None, is_bounded=True) -> View:
133159
layer = self.get_layer(layer_name)
134160
mag_ds = layer.get_mag(mag)
@@ -142,6 +168,10 @@ def _create_layer(self, layer_name, dtype, num_channels) -> Layer:
142168
def _get_properties_type(self):
143169
pass
144170

171+
@abstractmethod
172+
def _get_type(self):
173+
pass
174+
145175

146176
class WKDataset(AbstractDataset):
147177
@classmethod
@@ -177,6 +207,9 @@ def _create_layer(self, layer_name, dtype, num_channels) -> Layer:
177207
def _get_properties_type(self):
178208
return WKProperties
179209

210+
def _get_type(self):
211+
return WKDataset
212+
180213

181214
class TiffDataset(AbstractDataset):
182215
@classmethod
@@ -226,6 +259,9 @@ def _create_layer(self, layer_name, dtype, num_channels) -> Layer:
226259
def _get_properties_type(self):
227260
return TiffProperties
228261

262+
def _get_type(self):
263+
return TiffDataset
264+
229265

230266
class TiledTiffDataset(AbstractDataset):
231267
@classmethod
@@ -280,6 +316,9 @@ def _create_layer(self, layer_name, dtype, num_channels) -> Layer:
280316
def _get_properties_type(self):
281317
return TiffProperties
282318

319+
def _get_type(self):
320+
return TiledTiffDataset
321+
283322

284323
def validate_pattern(pattern):
285324
assert pattern.count("{") > 0 and pattern.count("}") > 0, (

0 commit comments

Comments
 (0)