Skip to content

Commit e615d60

Browse files
authored
Merge pull request #54 from computational-cell-analytics/export-updates
Update the data export scripts to preserve the label IDs of the IHC segmentations and their corresponding synapses. The segmentation must be exported as "uint16," which limits the number of SGN instances to the data type's maximum of 65,535. A warning will be displayed if the label is higher than this value. An offset option for the synapse IDs in the data export has been added to allow for different coloring in Imaris.
2 parents c649629 + c267eb3 commit e615d60

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

scripts/export_lower_resolution.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import argparse
22
import os
3+
import warnings
34

45
import numpy as np
56
import pandas as pd
67
import tifffile
78
import zarr
89

910
from flamingo_tools.s3_utils import get_s3_path, BUCKET_NAME, SERVICE_ENDPOINT
10-
# from skimage.segmentation import relabel_sequential
1111

1212

1313
def filter_component(fs, segmentation, cochlea, seg_name, components):
@@ -19,10 +19,12 @@ def filter_component(fs, segmentation, cochlea, seg_name, components):
1919
# Then we get the ids for the components and us them to filter the segmentation.
2020
component_mask = np.isin(table.component_labels.values, components)
2121
keep_label_ids = table.label_id.values[component_mask].astype("int64")
22+
if max(keep_label_ids) > np.iinfo("uint16").max:
23+
warnings.warn(f"Label ID exceeds maximum of data type 'uint16': {np.iinfo('uint16').max}.")
24+
2225
filter_mask = ~np.isin(segmentation, keep_label_ids)
2326
segmentation[filter_mask] = 0
24-
25-
# segmentation, _, _ = relabel_sequential(segmentation)
27+
segmentation = segmentation.astype("uint16")
2628
return segmentation
2729

2830

@@ -41,7 +43,7 @@ def export_lower_resolution(args):
4143
s3_store, fs = get_s3_path(internal_path, bucket_name=BUCKET_NAME, service_endpoint=SERVICE_ENDPOINT)
4244
with zarr.open(s3_store, mode="r") as f:
4345
data = f[input_key][:]
44-
print(data.shape)
46+
4547
if args.filter_by_components is not None:
4648
data = filter_component(fs, data, args.cochlea, channel, args.filter_by_components)
4749
if args.binarize:

scripts/export_synapse_detections.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from tqdm import tqdm
1313

1414

15-
def export_synapse_detections(cochlea, scale, output_folder, synapse_name, reference_ihcs, max_dist, radius):
15+
def export_synapse_detections(cochlea, scale, output_folder, synapse_name, reference_ihcs, max_dist, radius, id_offset):
1616
s3 = create_s3_target()
1717

1818
content = s3.open(f"{BUCKET_NAME}/{cochlea}/dataset.json", mode="r", encoding="utf-8")
@@ -53,22 +53,29 @@ def export_synapse_detections(cochlea, scale, output_folder, synapse_name, refer
5353
coordinates /= (2 ** scale)
5454
coordinates = np.round(coordinates, 0).astype("int")
5555

56+
ihc_ids = syn_table["matched_ihc"].values
57+
5658
# Create the output.
5759
output = np.zeros(shape, dtype="uint16")
5860
mask = ball(radius).astype(bool)
5961

60-
for coord in tqdm(coordinates, desc="Writing synapses to volume"):
62+
for coord, matched_ihc in tqdm(
63+
zip(coordinates, ihc_ids), total=len(coordinates), desc="Writing synapses to volume"
64+
):
6165
bb = tuple(slice(c - radius, c + radius + 1) for c in coord)
6266
try:
63-
output[bb][mask] = 1
67+
output[bb][mask] = matched_ihc + id_offset
6468
except IndexError:
6569
print("Index error for", coord)
6670
continue
6771

6872
# Write the output.
6973
out_folder = os.path.join(output_folder, cochlea, f"scale{scale}")
7074
os.makedirs(out_folder, exist_ok=True)
71-
out_path = os.path.join(out_folder, f"{synapse_name}.tif")
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")
7279
print("Writing synapses to", out_path)
7380
tifffile.imwrite(out_path, output, bigtiff=True, compression="zlib")
7481

@@ -78,16 +85,18 @@ def main():
7885
parser.add_argument("--cochlea", "-c", required=True)
7986
parser.add_argument("--scale", "-s", type=int, required=True)
8087
parser.add_argument("--output_folder", "-o", required=True)
81-
parser.add_argument("--synapse_name", default="synapse_v3_ihc_v4")
82-
parser.add_argument("--reference_ihcs", default="IHC_v4")
88+
parser.add_argument("--synapse_name", default="synapse_v3_ihc_v4b")
89+
parser.add_argument("--reference_ihcs", default="IHC_v4b")
8390
parser.add_argument("--max_dist", type=float, default=3.0)
8491
parser.add_argument("--radius", type=int, default=3)
92+
parser.add_argument("--id_offset", type=int, default=0)
8593
args = parser.parse_args()
8694

8795
export_synapse_detections(
8896
args.cochlea, args.scale, args.output_folder,
8997
args.synapse_name, args.reference_ihcs,
90-
args.max_dist, args.radius
98+
args.max_dist, args.radius,
99+
args.id_offset,
91100
)
92101

93102

0 commit comments

Comments
 (0)