Skip to content

Commit 1f392ef

Browse files
Add evaluation scripts for cooper data
1 parent ce94ea8 commit 1f392ef

20 files changed

+857
-36
lines changed

scripts/cooper/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
pwd.txt
2+
debug/
3+
mito/
4+
synapse-examples/
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import os
2+
from glob import glob
3+
4+
import h5py
5+
import napari
6+
import numpy as np
7+
8+
from magicgui import magicgui
9+
from scipy.ndimage import binary_dilation, binary_opening
10+
from skimage.measure import label
11+
12+
13+
def postprocess_az(thin_az_seg):
14+
# seg = binary_dilation(thin_az_seg, iterations=1)
15+
# seg = binary_opening(seg)
16+
seg = label(thin_az_seg)
17+
18+
ids, sizes = np.unique(seg, return_counts=True)
19+
ids, sizes = ids[1:], sizes[1:]
20+
seg = seg == ids[np.argmax(sizes)].astype("uint8")
21+
return seg
22+
23+
24+
def process_az(raw_path, az_path):
25+
with h5py.File(raw_path, "r") as f:
26+
raw = f["raw"][:]
27+
28+
with h5py.File(az_path, "r") as f:
29+
seg = f["thin_az"][:]
30+
31+
seg_pp = postprocess_az(seg)
32+
33+
v = napari.Viewer()
34+
v.add_image(raw)
35+
v.add_labels(seg, opacity=1, visible=True)
36+
segl = v.add_labels(seg_pp, opacity=1)
37+
segl.new_colormap()
38+
v.title = raw_path
39+
napari.run()
40+
41+
42+
def check_all_postprocessed():
43+
raw_paths = sorted(glob(os.path.join("imig_data/**/*.h5"), recursive=True))
44+
seg_paths = sorted(glob(os.path.join("az_segmentation/**/*.h5"), recursive=True))
45+
assert len(raw_paths) == len(seg_paths)
46+
for raw_path, seg_path in zip(raw_paths, seg_paths):
47+
process_az(raw_path, seg_path)
48+
49+
50+
def proofread_file(raw_path, az_path, out_root):
51+
ds, fname = os.path.split(raw_path)
52+
ds = os.path.basename(ds)
53+
54+
out_folder = os.path.join(out_root, ds)
55+
os.makedirs(out_folder, exist_ok=True)
56+
out_path = os.path.join(out_folder, fname)
57+
58+
if os.path.exists(out_path):
59+
return
60+
61+
with h5py.File(raw_path, "r") as f:
62+
raw = f["raw"][:]
63+
64+
with h5py.File(az_path, "r") as f:
65+
seg = f["thin_az"][:]
66+
67+
seg_pp = postprocess_az(seg)
68+
69+
v = napari.Viewer()
70+
v.add_image(raw)
71+
v.add_labels(seg, opacity=1, visible=True, name="original")
72+
segl = v.add_labels(seg_pp, opacity=1, name="postprocessed")
73+
segl.new_colormap()
74+
75+
v.title = raw_path
76+
77+
@magicgui(call_button="Postprocess")
78+
def postprocess():
79+
seg = v.layers["postprocessed"].data
80+
seg = postprocess_az(seg)
81+
v.layers["postprocessed"].data = seg
82+
83+
@magicgui(call_button="Save")
84+
def save():
85+
seg = v.layers["postprocessed"].data
86+
with h5py.File(out_path, "a") as f:
87+
f.create_dataset("az_thin_proofread", data=seg, compression="gzip")
88+
print("Save done!")
89+
90+
v.window.add_dock_widget(postprocess)
91+
v.window.add_dock_widget(save)
92+
93+
napari.run()
94+
95+
96+
def proofread_az(out_folder):
97+
raw_paths = sorted(glob(os.path.join("imig_data/**/*.h5"), recursive=True))
98+
seg_paths = sorted(glob(os.path.join("az_segmentation/**/*.h5"), recursive=True))
99+
assert len(raw_paths) == len(seg_paths)
100+
os.makedirs(out_folder, exist_ok=True)
101+
for i, (raw_path, seg_path) in enumerate(zip(raw_paths, seg_paths)):
102+
print(i, "/", len(seg_paths))
103+
proofread_file(raw_path, seg_path, out_folder)
104+
105+
106+
def main():
107+
# check_all_postprocessed()
108+
# process_az(
109+
# "./imig_data/Munc13DKO/A_M13DKO_060212_DKO1.1_crop.h5",
110+
# "./az_segmentation/Munc13DKO/A_M13DKO_060212_DKO1.1_crop.h5"
111+
# )
112+
proofread_az("./proofread_az")
113+
114+
115+
if __name__ == "__main__":
116+
main()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from elf.io import open_file
2+
3+
4+
def test_export():
5+
from synaptic_reconstruction.imod.to_imod import write_segmentation_to_imod_as_points
6+
from subprocess import run
7+
8+
mrc_path = "20241108_3D_Imig_DATA_2014/!_M13DKO_TOMO_DATA_Imig2014_mrc-mod-FM/A_M13DKO_080212_CTRL4.8_crop/A_M13DKO_080212_CTRL4.8_crop.mrc" # noqa
9+
seg_path = "imig_data/Munc13DKO/A_M13DKO_080212_CTRL4.8_crop.h5"
10+
out_path = "exported_vesicles.mod"
11+
12+
with open_file(seg_path, "r") as f:
13+
seg = f["vesicles/segment_from_combined_vesicles"][:]
14+
15+
# !!!! 0.7
16+
write_segmentation_to_imod_as_points(
17+
mrc_path, seg, out_path, min_radius=10, radius_factor=0.7
18+
)
19+
run(["imod", mrc_path, out_path])
20+
21+
22+
test_export()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import os
2+
3+
import h5py
4+
import napari
5+
6+
from magicgui import magicgui
7+
8+
9+
def correct_manual_az(raw_path, seg_path):
10+
with h5py.File(raw_path, "r") as f:
11+
raw = f["raw"][:]
12+
13+
seg_key = "az_thin_proofread"
14+
with h5py.File(seg_path, "r") as f:
15+
seg = f[seg_key][:]
16+
17+
v = napari.Viewer()
18+
v.add_image(raw)
19+
v.add_labels(seg)
20+
21+
@magicgui(call_button="save")
22+
def save():
23+
seg = v.layers["seg"].data
24+
with h5py.File(seg_path, "a") as f:
25+
f[seg_key][:] = seg
26+
27+
v.window.add_dock_widget(save)
28+
29+
napari.run()
30+
31+
32+
def main():
33+
to_correct = [
34+
# ("Munc13DKO", "B_M13DKO_080212_CTRL4.8_crop"),
35+
# ("SNAP25", "A_SNAP25_12082_KO1.2_6_crop"),
36+
# ("SNAP25", "B_SNAP25_120812_CTRL1.3_13_crop"),
37+
("SNAP25", "B_SNAP25_12082_KO1.2_6_crop")
38+
]
39+
for ds, fname in to_correct:
40+
raw_path = os.path.join("imig_data", ds, f"{fname}.h5")
41+
seg_path = os.path.join("proofread_az", ds, f"{fname}.h5")
42+
assert os.path.exists(raw_path)
43+
assert os.path.exists(seg_path)
44+
correct_manual_az(raw_path, seg_path)
45+
46+
47+
if __name__ == "__main__":
48+
main()

scripts/cooper/analysis/export_az_to_imod.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ def check_imod(tomo_path, mod_path):
1616

1717

1818
def export_all_to_imod(check_input=True, check_export=True):
19-
files = sorted(glob("./az_segmentation/**/*.h5", recursive=True))
19+
files = sorted(glob("./proofread_az/**/*.h5", recursive=True))
2020
mrc_root = "./mrc_files"
2121
output_folder = "./az_export/initial_model"
2222

23+
ratings = pd.read_excel("quality_ratings/az_quality_clean_FM.xlsx")
24+
2325
for ff in files:
2426
ds, fname = os.path.split(ff)
2527
ds = os.path.basename(ds)
@@ -28,12 +30,26 @@ def export_all_to_imod(check_input=True, check_export=True):
2830
if os.path.exists(out_path):
2931
continue
3032

33+
restrict_to_good_azs = False
34+
if restrict_to_good_azs:
35+
tomo_name = os.path.splitext(fname)[0]
36+
rating = ratings[
37+
(ratings["Dataset"] == ds) & (ratings["Tomogram"] == tomo_name)
38+
]["Rating"].values[0]
39+
if rating != "Good":
40+
print("Skipping", ds, tomo_name, "due to", rating)
41+
continue
42+
3143
os.makedirs(out_folder, exist_ok=True)
3244
mrc_path = os.path.join(mrc_root, ds, fname.replace(".h5", ".rec"))
3345
assert os.path.exists(mrc_path), mrc_path
3446

3547
with h5py.File(ff, "r") as f:
36-
seg = f["thin_az"][:]
48+
if "thin_az_corrected" in f:
49+
print("Loading corrected az!")
50+
seg = f["thin_az_corrected"][:]
51+
else:
52+
seg = f["az_thin_proofread"][:]
3753

3854
seg = binary_dilation(seg, iterations=2)
3955
seg = binary_closing(seg, iterations=2)
@@ -114,21 +130,21 @@ def measure_surfaces():
114130
result["AZ Surface"].append(area)
115131

116132
result = pd.DataFrame(result)
117-
result.to_excel("./az_measurements_all.xlsx", index=False)
133+
result.to_excel("./results/az_areas_all.xlsx", index=False)
118134

119135

120136
def filter_surfaces():
121-
all_results = pd.read_excel("./az_measurements_all.xlsx")
137+
all_results = pd.read_excel("./results/az_areas_all.xlsx")
122138
man_tomos = pd.read_csv("./man_tomos.tsv")
123139

124140
man_results = all_results.merge(man_tomos[["Dataset", "Tomogram"]], on=["Dataset", "Tomogram"], how="inner")
125-
man_results.to_excel("./az_measuerements_manual.xlsx", index=False)
141+
man_results.to_excel("./results/az_areas_manual.xlsx", index=False)
126142

127143

128144
def main():
129145
export_all_to_imod(False, False)
130146
smooth_all_surfaces(False)
131-
# measure_surfaces()
147+
measure_surfaces()
132148
filter_surfaces()
133149

134150

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import os
2+
from glob import glob
3+
4+
import numpy as np
5+
import pandas as pd
6+
7+
8+
def filter_sizes_by_distance(size_table, distance_table, out_dir, max_distance=100):
9+
fname = os.path.basename(size_table)
10+
print("Filtering vesicles for", fname)
11+
12+
size_table = pd.read_csv(size_table)
13+
distance_table = pd.read_csv(distance_table)
14+
assert (size_table.columns == distance_table.columns).all()
15+
out_columns = {}
16+
n_tot, n_filtered = 0, 0
17+
all_values = []
18+
for col_name in size_table.columns:
19+
size_values = size_table[col_name].values
20+
distance_values = distance_table[col_name].values
21+
size_values, distance_values = (
22+
size_values[np.isfinite(size_values)],
23+
distance_values[np.isfinite(distance_values)]
24+
)
25+
assert len(size_values) == len(distance_values)
26+
n_tot += len(size_values)
27+
mask = distance_values < max_distance
28+
out_columns[col_name] = size_values[mask]
29+
n_filtered += mask.sum()
30+
all_values.extend(size_values[mask].tolist())
31+
32+
print("Total number of vesicles:", n_tot)
33+
print("Number of vesicles after filtering:", n_filtered)
34+
print("Average diameter:", np.mean(all_values))
35+
os.makedirs(out_dir, exist_ok=True)
36+
out_path = os.path.join(out_dir, fname)
37+
38+
filtered_sizes = pd.DataFrame.from_dict(out_columns, orient='index').transpose()
39+
filtered_sizes.to_csv(out_path, index=False)
40+
41+
42+
def main():
43+
size_tables = sorted(glob("./results/diameters/*.csv"))
44+
distance_tables = sorted(glob("./results/distances/*.csv"))
45+
for size_tab, distance_tab in zip(size_tables, distance_tables):
46+
filter_sizes_by_distance(size_tab, distance_tab, "./results/filtered_diameters")
47+
48+
49+
if __name__ == "__main__":
50+
main()

0 commit comments

Comments
 (0)