11import argparse
22import json
33import os
4+ from typing import List
45
56import numpy as np
67import pandas as pd
1213from 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
83108def 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