|
25 | 25 |
|
26 | 26 | from PIL import Image |
27 | 27 | from kajiki import PackageLoader |
| 28 | +from zarr.storage import FSStore |
28 | 29 |
|
29 | 30 |
|
30 | 31 | log = logging.getLogger(__name__) |
31 | 32 |
|
32 | | -# version of the N5/Zarr layout |
33 | | -LAYOUT_VERSION = 1 |
| 33 | +# version of the Zarr layout |
| 34 | +LAYOUT_VERSION = 3 |
34 | 35 |
|
35 | 36 |
|
36 | 37 | class MaxQueuePool(object): |
@@ -79,20 +80,20 @@ def __exit__(self, exception_type, exception_value, traceback): |
79 | 80 | class WriteTiles(object): |
80 | 81 |
|
81 | 82 | def __init__( |
82 | | - self, tile_width, tile_height, resolutions, file_type, max_workers, |
83 | | - batch_size, input_path, output_path, fill_color |
| 83 | + self, tile_width, tile_height, resolutions, max_workers, |
| 84 | + batch_size, fill_color, nested, input_path, output_path |
84 | 85 | ): |
85 | 86 | self.tile_width = tile_width |
86 | 87 | self.tile_height = tile_height |
87 | 88 | self.resolutions = resolutions |
88 | | - self.file_type = file_type |
89 | 89 | self.max_workers = max_workers |
90 | 90 | self.batch_size = batch_size |
| 91 | + self.fill_color = fill_color |
| 92 | + self.nested = nested |
91 | 93 | self.input_path = input_path |
92 | 94 | self.slide_directory = output_path |
93 | | - self.fill_color = fill_color |
94 | 95 |
|
95 | | - os.makedirs(self.slide_directory, exist_ok=True) |
| 96 | + os.makedirs(os.path.join(self.slide_directory, "OME"), exist_ok=True) |
96 | 97 |
|
97 | 98 | render_context = softwarerendercontext.SoftwareRenderContext() |
98 | 99 | render_backend = softwarerenderbackend.SoftwareRenderBackend() |
@@ -378,7 +379,9 @@ def wait_any(self, regions): |
378 | 379 |
|
379 | 380 | def write_metadata(self): |
380 | 381 | '''write metadata to a JSON file''' |
381 | | - metadata_file = os.path.join(self.slide_directory, "METADATA.json") |
| 382 | + metadata_file = os.path.join( |
| 383 | + self.slide_directory, "OME", "METADATA.json" |
| 384 | + ) |
382 | 385 |
|
383 | 386 | with open(metadata_file, "w", encoding="utf-8") as f: |
384 | 387 | metadata = self.get_metadata() |
@@ -419,7 +422,9 @@ def write_metadata(self): |
419 | 422 | loader = PackageLoader() |
420 | 423 | template = loader.import_("isyntax2raw.resources.ome_template") |
421 | 424 | xml = template(xml_values).render() |
422 | | - ome_xml_file = os.path.join(self.slide_directory, "METADATA.ome.xml") |
| 425 | + ome_xml_file = os.path.join( |
| 426 | + self.slide_directory, "OME", "METADATA.ome.xml" |
| 427 | + ) |
423 | 428 | with open(ome_xml_file, "w", encoding="utf-8") as omexml: |
424 | 429 | omexml.write(xml) |
425 | 430 |
|
@@ -474,12 +479,15 @@ def write_image_type(self, image_type, series): |
474 | 479 | log.info("wrote %s image" % image_type) |
475 | 480 |
|
476 | 481 | def create_tile_directory(self, series, resolution, width, height): |
477 | | - tile_directory = os.path.join( |
478 | | - self.slide_directory, "data.%s" % self.file_type |
| 482 | + dimension_separator = '/' |
| 483 | + if not self.nested: |
| 484 | + dimension_separator = '.' |
| 485 | + self.zarr_store = FSStore( |
| 486 | + self.slide_directory, |
| 487 | + dimension_separator=dimension_separator, |
| 488 | + normalize_keys=True, |
| 489 | + auto_mkdir=True |
479 | 490 | ) |
480 | | - self.zarr_store = zarr.DirectoryStore(tile_directory) |
481 | | - if self.file_type == "n5": |
482 | | - self.zarr_store = zarr.N5Store(tile_directory) |
483 | 491 | self.zarr_group = zarr.group(store=self.zarr_store) |
484 | 492 | self.zarr_group.attrs['bioformats2raw.layout'] = LAYOUT_VERSION |
485 | 493 |
|
@@ -520,7 +528,7 @@ def write_tile( |
520 | 528 | x_end = x_start + tile_width |
521 | 529 | y_end = y_start + tile_height |
522 | 530 | try: |
523 | | - # N5/Zarr has a single n-dimensional array representation on |
| 531 | + # Zarr has a single n-dimensional array representation on |
524 | 532 | # disk (not interleaved RGB) |
525 | 533 | pixels = self.make_planar(pixels, tile_width, tile_height) |
526 | 534 | z = self.zarr_group["0/%d" % resolution] |
|
0 commit comments