|
30 | 30 | import time |
31 | 31 |
|
32 | 32 |
|
| 33 | +def build_straightened_tiff_metadata( |
| 34 | + volume_cache: VolumeCache, |
| 35 | + has_color_channels: bool, |
| 36 | + num_color_channels: int | None, |
| 37 | + annotation_points: np.ndarray | None = None, |
| 38 | +) -> dict: |
| 39 | + # Volume cache resolution is in voxel size, but .tiff XY resolution is in voxels per unit, so we invert. |
| 40 | + resolution = [1.0 / voxel_size for voxel_size in volume_cache.get_resolution_um()[:2] * 0.0001] |
| 41 | + resolutionunit = "CENTIMETER" |
| 42 | + |
| 43 | + metadata = { |
| 44 | + # Z Resolution doesn't have an inbuilt property or strong convention. |
| 45 | + "spacing": volume_cache.get_resolution_um()[2], |
| 46 | + "unit": "um", |
| 47 | + } |
| 48 | + if isinstance(annotation_points, np.ndarray): |
| 49 | + metadata["annotation_points"] = annotation_points.tolist() |
| 50 | + |
| 51 | + return { |
| 52 | + "software": "ouroboros", |
| 53 | + "resolution": resolution[:2] + [resolutionunit], |
| 54 | + "photometric": ( |
| 55 | + "rgb" if has_color_channels and num_color_channels and num_color_channels > 1 else "minisblack" |
| 56 | + ), |
| 57 | + "metadata": metadata, |
| 58 | + } |
| 59 | + |
| 60 | + |
33 | 61 | class SliceParallelPipelineStep(PipelineStep): |
34 | 62 | def __init__( |
35 | 63 | self, |
@@ -84,28 +112,18 @@ def _process(self, input_data: tuple[any]) -> None | str: |
84 | 112 | config.output_file_folder, f"{config.output_file_name}_temp" |
85 | 113 | ).with_suffix(".tif") |
86 | 114 |
|
87 | | - # Start setting up metadata |
88 | | - # Volume cache resolution is in voxel size, but .tiff XY resolution is in voxels per unit, so we invert. |
89 | | - resolution = [1.0 / voxel_size for voxel_size in volume_cache.get_resolution_um()[:2] * 0.0001] |
90 | | - resolutionunit = "CENTIMETER" |
91 | | - # However, Z Resolution doesn't have an inbuilt property or strong convention, so going with this. |
92 | | - metadata = { |
93 | | - "spacing": volume_cache.get_resolution_um()[2], |
94 | | - "unit": "um" |
95 | | - } |
96 | | - |
97 | 115 | # Determine the dimensions of the image |
98 | 116 | has_color_channels = volume_cache.has_color_channels() |
99 | 117 | num_color_channels = ( |
100 | 118 | volume_cache.get_num_channels() if has_color_channels else None |
101 | 119 | ) |
102 | 120 |
|
103 | | - tiff_metadata = { |
104 | | - "software": "ouroboros", |
105 | | - "resolution": resolution[:2] + [resolutionunit], # XY Resolution |
106 | | - "photometric": ("rgb" if has_color_channels and num_color_channels > 1 else "minisblack"), |
107 | | - "metadata": metadata |
108 | | - } |
| 121 | + tiff_metadata = build_straightened_tiff_metadata( |
| 122 | + volume_cache=volume_cache, |
| 123 | + has_color_channels=has_color_channels, |
| 124 | + num_color_channels=num_color_channels, |
| 125 | + annotation_points=pipeline_input.annotation_points, |
| 126 | + ) |
109 | 127 |
|
110 | 128 | # Create temporary memmap (single tif file with the same dimensions as the slices) |
111 | 129 | temp_shape = ( |
|
0 commit comments