Skip to content

Commit f630ee1

Browse files
Update otoferlin analysis
1 parent 69d5021 commit f630ee1

File tree

4 files changed

+135
-6
lines changed

4 files changed

+135
-6
lines changed

scripts/otoferlin/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
data/
2+
sync_segmentation.sh
3+
segmentation/
4+
results/

scripts/otoferlin/common.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ def get_folders():
3636
return INPUT_ROOT, OUTPUT_ROOT
3737
root_in = "./data/tomograms"
3838
assert os.path.exists(root_in)
39-
root_out = "./data/segmentation"
40-
return root_in, root_out
39+
return root_in, OUTPUT_ROOT
4140

4241

4342
def get_all_tomograms():
@@ -89,6 +88,12 @@ def load_segmentations(seg_path):
8988
return segmentations
9089

9190

91+
def to_condition(mrc_path):
92+
fname = os.path.basename(mrc_path)
93+
# TODO: Is this correct, or is it the otherway round?
94+
return "MUT" if fname.startswith("Otof") else "WT"
95+
96+
9297
if __name__ == "__main__":
9398
tomos = get_all_tomograms()
9499
print("We have", len(tomos), "tomograms")

scripts/otoferlin/correct_vesicle_pools.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ def _create_pool_layer(seg, assignment_path):
1818

1919
pool_colors = get_colormaps()["pools"]
2020
colormap = {}
21-
for pool_id, pool_name in enumerate(pool_names, 1):
22-
pool_vesicle_ids = assignments[assignments.pool == pool_name].vesicle_id
21+
for pool_id, pool_name in enumerate(pool_names):
22+
if not isinstance(pool_name, str) and np.isnan(pool_name):
23+
continue
24+
pool_vesicle_ids = assignments[assignments.pool == pool_name].vesicle_id.values
2325
pool_mask = np.isin(seg, pool_vesicle_ids)
2426
pools[pool_mask] = pool_id
2527
colormap[pool_id] = pool_colors[pool_name]
@@ -37,7 +39,7 @@ def _update_assignments(vesicles, pool_correction, assignment_path):
3739
correction_val = prop.max_intensity
3840
if correction_val == 0:
3941
continue
40-
new_assignments[new_assignments.vesicle_id == prop.label] = val_to_pool[correction_val]
42+
new_assignments[new_assignments.vesicle_id == prop.label].pool = val_to_pool[correction_val]
4143

4244
new_assignments.to_csv(assignment_path, index=False)
4345

@@ -48,6 +50,9 @@ def correct_vesicle_pools(mrc_path):
4850

4951
output_folder = os.path.split(seg_path)[0]
5052
assignment_path = os.path.join(output_folder, "vesicle_pools.csv")
53+
if not os.path.exists(assignment_path):
54+
print("Skip", seg_path, "due to missing assignments")
55+
return
5156

5257
data, _ = read_mrc(mrc_path)
5358
segmentations = load_segmentations(seg_path)
@@ -62,6 +67,7 @@ def correct_vesicle_pools(mrc_path):
6267
vesicle_pools, pool_colors = _create_pool_layer(vesicles, assignment_path)
6368

6469
pool_correction_path = os.path.join(output_folder, "correction", "pool_correction.tif")
70+
os.makedirs(os.path.join(output_folder, "correction"), exist_ok=True)
6571
if os.path.exists(pool_correction_path):
6672
pool_correction = imageio.imread(pool_correction_path)
6773
else:
@@ -81,9 +87,10 @@ def update_pools(viewer: napari.Viewer):
8187
vesicles = viewer.layers["vesicles"].data
8288
pool_correction = viewer.layers["pool_correction"].data
8389
_update_assignments(vesicles, pool_correction, assignment_path)
84-
imageio.imwrite(pool_correction_path, pool_correction, compression="zlib")
90+
# imageio.imwrite(pool_correction_path, pool_correction, compression="zlib")
8591
pool_data, pool_colors = _create_pool_layer(vesicles, assignment_path)
8692
viewer.layers["vesicle_pools"].data = pool_data
93+
viewer.layers["vesicle_pools"].colormap = pool_colors
8794

8895
v.window.add_dock_widget(update_pools)
8996

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import os
2+
from datetime import datetime
3+
4+
import numpy as np
5+
import pandas as pd
6+
from common import get_all_tomograms, get_seg_path, to_condition
7+
8+
from synapse_net.distance_measurements import load_distances
9+
10+
11+
def get_output_folder():
12+
output_root = "./results"
13+
date = datetime.now().strftime("%Y%m%d")
14+
15+
version = 1
16+
output_folder = os.path.join(output_root, f"{date}_{version}")
17+
while os.path.exists(output_folder):
18+
version += 1
19+
output_folder = os.path.join(output_root, f"{date}_{version}")
20+
21+
os.makedirs(output_folder)
22+
return output_folder
23+
24+
25+
def _export_results(tomograms, result_path, result_extraction):
26+
results = {}
27+
for tomo in tomograms:
28+
condition = to_condition(tomo)
29+
res = result_extraction(tomo)
30+
if condition in results:
31+
results[condition].append(res)
32+
else:
33+
results[condition] = [res]
34+
35+
for condition, res in results.items():
36+
res = pd.concat(res)
37+
if os.path.exists(result_path):
38+
with pd.ExcelWriter(result_path, engine="openpyxl", mode="a") as writer:
39+
res.to_excel(writer, sheet_name=condition, index=False)
40+
else:
41+
res.to_excel(result_path, sheet_name=condition, index=False)
42+
43+
44+
def export_vesicle_pools(tomograms, result_path):
45+
46+
def result_extraction(tomo):
47+
folder = os.path.split(get_seg_path(tomo))[0]
48+
measure_path = os.path.join(folder, "vesicle_pools.csv")
49+
measures = pd.read_csv(measure_path).dropna()
50+
pool_names, counts = np.unique(measures.pool.values, return_counts=True)
51+
res = {"tomogram": [os.path.basename(tomo)]}
52+
res.update({k: v for k, v in zip(pool_names, counts)})
53+
res = pd.DataFrame(res)
54+
return res
55+
56+
_export_results(tomograms, result_path, result_extraction)
57+
58+
59+
def export_distances(tomograms, result_path):
60+
def result_extraction(tomo):
61+
folder = os.path.split(get_seg_path(tomo))[0]
62+
measure_path = os.path.join(folder, "vesicle_pools.csv")
63+
measures = pd.read_csv(measure_path).dropna()
64+
65+
measures = measures[measures.pool.isin(["MP-V", "Docked-V"])][["vesicle_id", "pool"]]
66+
67+
# Load the distances to PD.
68+
pd_distances, _, _, seg_ids = load_distances(os.path.join(folder, "distances", "PD.npz"))
69+
pd_distances = {sid: dist for sid, dist in zip(seg_ids, pd_distances)}
70+
measures["distance-to-pd"] = [pd_distances[vid] for vid in measures.vesicle_id.values]
71+
72+
# Load the distances to membrane.
73+
mem_distances, _, _, seg_ids = load_distances(os.path.join(folder, "distances", "membrane.npz"))
74+
mem_distances = {sid: dist for sid, dist in zip(seg_ids, mem_distances)}
75+
measures["distance-to-membrane"] = [mem_distances[vid] for vid in measures.vesicle_id.values]
76+
77+
measures = measures.drop(columns=["vesicle_id"])
78+
measures.insert(0, "tomogram", len(measures) * [os.path.basename(tomo)])
79+
80+
return measures
81+
82+
_export_results(tomograms, result_path, result_extraction)
83+
84+
85+
def export_diameter(tomograms, result_path):
86+
def result_extraction(tomo):
87+
folder = os.path.split(get_seg_path(tomo))[0]
88+
measure_path = os.path.join(folder, "vesicle_pools.csv")
89+
measures = pd.read_csv(measure_path).dropna()
90+
91+
measures = measures[measures.pool.isin(["MP-V", "Docked-V"])][["pool", "diameter"]]
92+
measures.insert(0, "tomogram", len(measures) * [os.path.basename(tomo)])
93+
94+
return measures
95+
96+
_export_results(tomograms, result_path, result_extraction)
97+
98+
99+
def main():
100+
tomograms = get_all_tomograms()
101+
result_folder = get_output_folder()
102+
103+
result_path = os.path.join(result_folder, "vesicle_pools.xlsx")
104+
export_vesicle_pools(tomograms, result_path)
105+
106+
result_path = os.path.join(result_folder, "distances.xlsx")
107+
export_distances(tomograms, result_path)
108+
109+
result_path = os.path.join(result_folder, "diameter.xlsx")
110+
export_diameter(tomograms, result_path)
111+
112+
113+
if __name__ == "__main__":
114+
main()

0 commit comments

Comments
 (0)