Skip to content

Commit e0860cb

Browse files
committed
Improved functionality for exporting synapses
1 parent 8e5e25a commit e0860cb

File tree

1 file changed

+69
-43
lines changed

1 file changed

+69
-43
lines changed

scripts/export_synapse_detections.py

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import argparse
22
import json
33
import os
4+
from typing import List
45

56
import numpy as np
67
import pandas as pd
@@ -12,7 +13,30 @@
1213
from tqdm import tqdm
1314

1415

15-
def export_synapse_detections(cochlea, scale, output_folder, synapse_name, reference_ihcs, max_dist, radius, id_offset):
16+
def export_synapse_detections(
17+
cochlea: str,
18+
scales: List[int],
19+
output_folder: str,
20+
synapse_name: str,
21+
reference_ihcs: str,
22+
max_dist: float,
23+
radius: float,
24+
id_offset: int,
25+
filter_ihc_components: List[int],
26+
):
27+
"""Export synapse detections fro lower resolutions.
28+
29+
Args:
30+
cochlea: Cochlea name on S3 bucket.
31+
scales: Scale for export of lower resolution.
32+
output_folder:
33+
synapse_name:
34+
reference_ihcs: Name of IHC segmentation.
35+
max_dist: Maximal distance of synapse to IHC segmentation.
36+
radius:
37+
id_offset: Offset of label id of synapse output to have different colours for visualization.
38+
filter_ihc_components: Component label(s) for filtering IHC segmentation.
39+
"""
1640
s3 = create_s3_target()
1741

1842
content = s3.open(f"{BUCKET_NAME}/{cochlea}/dataset.json", mode="r", encoding="utf-8")
@@ -36,67 +60,69 @@ def export_synapse_detections(cochlea, scale, output_folder, synapse_name, refer
3660
seg_table = pd.read_csv(seg_table_content, sep="\t")
3761

3862
# Only keep synapses that match to segmented IHCs of the main component.
39-
valid_ihcs = seg_table[seg_table.component_labels == 1].label_id
63+
valid_ihcs = seg_table[seg_table.component_labels.isin(filter_ihc_components)].label_id
4064
syn_table = syn_table[syn_table.matched_ihc.isin(valid_ihcs)]
4165

42-
# Get the reference shape at the given scale level.
43-
seg_path = os.path.join(cochlea, reference_seg_info["imageData"]["ome.zarr"]["relativePath"])
44-
s3_store, _ = get_s3_path(seg_path, bucket_name=BUCKET_NAME, service_endpoint=SERVICE_ENDPOINT)
45-
input_key = f"s{scale}"
46-
with zarr.open(s3_store, mode="r") as f:
47-
shape = f[input_key].shape
48-
49-
# Scale the coordinates according to the scale level.
50-
resolution = 0.38
51-
coordinates = syn_table[["z", "y", "x"]].values
52-
coordinates /= resolution
53-
coordinates /= (2 ** scale)
54-
coordinates = np.round(coordinates, 0).astype("int")
55-
56-
ihc_ids = syn_table["matched_ihc"].values
57-
58-
# Create the output.
59-
output = np.zeros(shape, dtype="uint16")
60-
mask = ball(radius).astype(bool)
61-
62-
for coord, matched_ihc in tqdm(
63-
zip(coordinates, ihc_ids), total=len(coordinates), desc="Writing synapses to volume"
64-
):
65-
bb = tuple(slice(c - radius, c + radius + 1) for c in coord)
66-
try:
67-
output[bb][mask] = matched_ihc + id_offset
68-
except IndexError:
69-
print("Index error for", coord)
70-
continue
71-
72-
# Write the output.
73-
out_folder = os.path.join(output_folder, cochlea, f"scale{scale}")
74-
os.makedirs(out_folder, exist_ok=True)
75-
if id_offset != 0:
76-
out_path = os.path.join(out_folder, f"{synapse_name}_offset{id_offset}.tif")
77-
else:
78-
out_path = os.path.join(out_folder, f"{synapse_name}.tif")
79-
print("Writing synapses to", out_path)
80-
tifffile.imwrite(out_path, output, bigtiff=True, compression="zlib")
66+
for scale in scales:
67+
# Get the reference shape at the given scale level.
68+
seg_path = os.path.join(cochlea, reference_seg_info["imageData"]["ome.zarr"]["relativePath"])
69+
s3_store, _ = get_s3_path(seg_path, bucket_name=BUCKET_NAME, service_endpoint=SERVICE_ENDPOINT)
70+
input_key = f"s{scale}"
71+
with zarr.open(s3_store, mode="r") as f:
72+
shape = f[input_key].shape
73+
74+
# Scale the coordinates according to the scale level.
75+
resolution = 0.38
76+
coordinates = syn_table[["z", "y", "x"]].values
77+
coordinates /= resolution
78+
coordinates /= (2 ** scale)
79+
coordinates = np.round(coordinates, 0).astype("int")
80+
81+
ihc_ids = syn_table["matched_ihc"].values
82+
83+
# Create the output.
84+
output = np.zeros(shape, dtype="uint16")
85+
mask = ball(radius).astype(bool)
86+
87+
for coord, matched_ihc in tqdm(
88+
zip(coordinates, ihc_ids), total=len(coordinates), desc="Writing synapses to volume"
89+
):
90+
bb = tuple(slice(c - radius, c + radius + 1) for c in coord)
91+
try:
92+
output[bb][mask] = matched_ihc + id_offset
93+
except IndexError:
94+
print("Index error for", coord)
95+
continue
96+
97+
# Write the output.
98+
out_folder = os.path.join(output_folder, cochlea, f"scale{scale}")
99+
os.makedirs(out_folder, exist_ok=True)
100+
if id_offset != 0:
101+
out_path = os.path.join(out_folder, f"{synapse_name}_offset{id_offset}.tif")
102+
else:
103+
out_path = os.path.join(out_folder, f"{synapse_name}.tif")
104+
print("Writing synapses to", out_path)
105+
tifffile.imwrite(out_path, output, bigtiff=True, compression="zlib")
81106

82107

83108
def main():
84109
parser = argparse.ArgumentParser()
85110
parser.add_argument("--cochlea", "-c", required=True)
86-
parser.add_argument("--scale", "-s", type=int, required=True)
111+
parser.add_argument("--scale", "-s", nargs="+", type=int, required=True)
87112
parser.add_argument("--output_folder", "-o", required=True)
88113
parser.add_argument("--synapse_name", default="synapse_v3_ihc_v4b")
89114
parser.add_argument("--reference_ihcs", default="IHC_v4b")
90115
parser.add_argument("--max_dist", type=float, default=3.0)
91116
parser.add_argument("--radius", type=int, default=3)
92117
parser.add_argument("--id_offset", type=int, default=0)
118+
parser.add_argument("--filter_ihc_components", nargs="+", type=int, default=[1])
93119
args = parser.parse_args()
94120

95121
export_synapse_detections(
96122
args.cochlea, args.scale, args.output_folder,
97123
args.synapse_name, args.reference_ihcs,
98124
args.max_dist, args.radius,
99-
args.id_offset,
125+
args.id_offset, args.filter_ihc_components,
100126
)
101127

102128

0 commit comments

Comments
 (0)