Skip to content

Commit 05d248d

Browse files
committed
Tools for the reproducibility of extraction of blocks and post-processing of SGNs
1 parent 3cdefa4 commit 05d248d

File tree

9 files changed

+641
-100
lines changed

9 files changed

+641
-100
lines changed

flamingo_tools/extract_block.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import os
2+
from typing import Optional, List
3+
4+
import imageio.v3 as imageio
5+
import numpy as np
6+
import zarr
7+
8+
import flamingo_tools.s3_utils as s3_utils
9+
from flamingo_tools.file_utils import read_image_data
10+
11+
12+
def extract_block(
13+
input_path: str,
14+
coords: List[int],
15+
output_dir: Optional[str] = None,
16+
input_key: Optional[str] = None,
17+
output_key: Optional[str] = None,
18+
resolution: float = 0.38,
19+
roi_halo: List[int] = [128, 128, 64],
20+
tif: bool = False,
21+
s3: Optional[bool] = False,
22+
s3_credentials: Optional[str] = None,
23+
s3_bucket_name: Optional[str] = None,
24+
s3_service_endpoint: Optional[str] = None,
25+
):
26+
"""Extract block around coordinate from input data according to a given halo.
27+
Either from a local file or from an S3 bucket.
28+
29+
Args:
30+
input_path: Input folder in n5 / ome-zarr format.
31+
coords: Center coordinates of extracted 3D volume.
32+
output_dir: Output directory for saving output as <basename>_crop.n5. Default: input directory.
33+
input_key: Input key for data in input file.
34+
output_key: Output key for data in n5 output or used as suffix for tif output.
35+
roi_halo: ROI halo of extracted 3D volume.
36+
tif: Flag for tif output
37+
s3: Flag for considering input_path for S3 bucket.
38+
s3_bucket_name: S3 bucket name.
39+
s3_service_endpoint: S3 service endpoint.
40+
s3_credentials: File path to credentials for S3 bucket.
41+
"""
42+
coords = [int(round(c)) for c in coords]
43+
coord_string = "-".join([str(c).zfill(4) for c in coords])
44+
45+
# Dimensions are inversed to view in MoBIE (x y z) -> (z y x)
46+
coords.reverse()
47+
roi_halo.reverse()
48+
49+
input_content = list(filter(None, input_path.split("/")))
50+
51+
if s3:
52+
image_name = input_content[-1].split(".")[0]
53+
if len(image_name.split("_")) > 1:
54+
resized_suffix = "_resized"
55+
image_prefix = image_name.split("_")[0]
56+
else:
57+
resized_suffix = ""
58+
image_prefix = image_name
59+
basename = input_content[0] + resized_suffix
60+
else:
61+
basename = "".join(input_content[-1].split(".")[:-1])
62+
image_prefix = basename.split("_")[-1]
63+
64+
input_dir = input_path.split(basename)[0]
65+
input_dir = os.path.abspath(input_dir)
66+
67+
if output_dir == "":
68+
output_dir = input_dir
69+
70+
if tif:
71+
if output_key is None:
72+
output_name = basename + "_crop_" + coord_string + "_" + image_prefix + ".tif"
73+
else:
74+
output_name = basename + "_" + image_prefix + "_crop_" + coord_string + "_" + output_key + ".tif"
75+
76+
output_file = os.path.join(output_dir, output_name)
77+
else:
78+
output_key = "raw" if output_key is None else output_key
79+
output_file = os.path.join(output_dir, basename + "_crop_" + coord_string + ".n5")
80+
81+
coords = np.array(coords)
82+
coords = coords / resolution
83+
coords = np.round(coords).astype(np.int32)
84+
85+
roi = tuple(slice(co - rh, co + rh) for co, rh in zip(coords, roi_halo))
86+
87+
if s3:
88+
input_path, fs = s3_utils.get_s3_path(input_path, bucket_name=s3_bucket_name,
89+
service_endpoint=s3_service_endpoint, credential_file=s3_credentials)
90+
91+
data_ = read_image_data(input_path, input_key)
92+
data_roi = data_[roi]
93+
94+
if tif:
95+
imageio.imwrite(output_file, data_roi, compression="zlib")
96+
else:
97+
with zarr.open(output_file, mode="w") as f_out:
98+
f_out.create_dataset(output_key, data=data_roi, compression="gzip")

reproducibility/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Scripts to ensure/facilitate the reproducbility of pre-/post-processing
2+
3+
The scripts within these folders document steps involved in the pre-/post-processing or analysis of data.
4+
The folders contain a script for reproducibility as well as dictionaries in JSON format, which contain script parameters and additional information.
5+
6+
## Extraction of blocks from a 3D volume
7+
8+
The extraction of blocks from a 3D volume is required for the creation of annotations, empty crops, or others regions of interest.
9+
10+
Usage:
11+
```
12+
python repro_block_extraction.py --input <JSON-file> --output <out-dir>
13+
```
14+
15+
## Post-processing of SGN segmentation
16+
17+
The post-processing of the SGN segmentation may involve the erosion of the segmentation to exclude artifacts, the variation of the minimal number of nodes within a component, or the minimal distance between nodes to consider them the same component.
18+
19+
Usage:
20+
```
21+
python repro_postprocess_sgn_v1.py --input <JSON-file> --output <out-dir>
22+
```
23+
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000144_L",
4+
"image_channel": "PV_resized",
5+
"crop_centers": [
6+
[
7+
1040,
8+
700,
9+
1390
10+
],
11+
[
12+
1300,
13+
690,
14+
1191
15+
],
16+
[
17+
1455,
18+
814,
19+
1191
20+
]
21+
],
22+
"halo_size": [
23+
128,
24+
128,
25+
32
26+
]
27+
},
28+
{
29+
"cochlea": "M_LR_000145_L",
30+
"image_channel": "PV_resized",
31+
"crop_centers": [
32+
[
33+
972,
34+
862,
35+
610
36+
],
37+
[
38+
1301,
39+
812,
40+
740
41+
]
42+
],
43+
"halo_size": [
44+
128,
45+
128,
46+
32
47+
]
48+
},
49+
{
50+
"cochlea": "M_LR_000167_R",
51+
"image_channel": "PV",
52+
"crop_centers": [
53+
[
54+
909,
55+
813,
56+
810
57+
],
58+
[
59+
916,
60+
800,
61+
722
62+
],
63+
[
64+
951,
65+
742,
66+
652
67+
],
68+
[
69+
951,
70+
742,
71+
602
72+
],
73+
[
74+
1251,
75+
266,
76+
575
77+
],
78+
[
79+
1210,
80+
148,
81+
606
82+
],
83+
[
84+
1305,
85+
341,
86+
526
87+
],
88+
[
89+
1137,
90+
669,
91+
1044
92+
]
93+
],
94+
"halo_size": [
95+
128,
96+
128,
97+
32
98+
]
99+
},
100+
{
101+
"cochlea": "M_LR_000151_R",
102+
"image_channel": "PV_resized",
103+
"crop_centers": [
104+
[
105+
1275,
106+
806,
107+
578
108+
],
109+
[
110+
875,
111+
539,
112+
747
113+
],
114+
[
115+
1300,
116+
535,
117+
747
118+
]
119+
],
120+
"halo_size": [
121+
128,
122+
128,
123+
32
124+
]
125+
},
126+
{
127+
"cochlea": "M_LR_000184_L",
128+
"image_channel": "PV_resized",
129+
"crop_centers": [
130+
[
131+
1326,
132+
844,
133+
516
134+
],
135+
[
136+
885,
137+
913,
138+
1023
139+
]
140+
],
141+
"halo_size": [
142+
128,
143+
128,
144+
32
145+
]
146+
}
147+
]
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000144_L",
4+
"image_channel": "PV_resized",
5+
"crop_centers": [
6+
[
7+
1490,
8+
600,
9+
735
10+
],
11+
[
12+
1540,
13+
930,
14+
865
15+
]
16+
],
17+
"halo_size": [
18+
256,
19+
256,
20+
128
21+
]
22+
},
23+
{
24+
"cochlea": "M_LR_000145_L",
25+
"image_channel": "PV_resized",
26+
"crop_centers": [
27+
[
28+
1300,
29+
700,
30+
700
31+
]
32+
],
33+
"halo_size": [
34+
256,
35+
256,
36+
128
37+
]
38+
},
39+
{
40+
"cochlea": "M_LR_000151_R",
41+
"image_channel": "PV_resized",
42+
"crop_centers": [
43+
[
44+
1350,
45+
690,
46+
1000
47+
],
48+
[
49+
1350,
50+
570,
51+
734
52+
]
53+
],
54+
"halo_size": [
55+
256,
56+
256,
57+
128
58+
]
59+
},
60+
{
61+
"cochlea": "M_LR_000155_L",
62+
"image_channel": "PV_resized",
63+
"crop_centers": [
64+
[
65+
900,
66+
1090,
67+
700
68+
],
69+
[
70+
1464,
71+
830,
72+
420
73+
]
74+
],
75+
"halo_size": [
76+
256,
77+
256,
78+
128
79+
]
80+
},
81+
{
82+
"cochlea": "M_LR_000167_R",
83+
"image_channel": "PV",
84+
"crop_centers": [
85+
[
86+
1360,
87+
1040,
88+
840
89+
],
90+
[
91+
900,
92+
780,
93+
780
94+
]
95+
],
96+
"halo_size": [
97+
256,
98+
256,
99+
128
100+
]
101+
}
102+
]

0 commit comments

Comments
 (0)