Skip to content

Sm dev #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e2c4f4b
AZ segmentation
SarahMuth Oct 23, 2024
a0f713f
updates
SarahMuth Oct 28, 2024
94f9121
Merge branch 'main' of https://github.com/computational-cell-analytic…
SarahMuth Oct 28, 2024
ac1ac00
update 2D DA
SarahMuth Oct 28, 2024
37de75d
Merge branch 'main' of https://github.com/computational-cell-analytic…
SarahMuth Oct 29, 2024
61c57fa
small updates, compartment segmentation
SarahMuth Nov 7, 2024
40e965e
Implement code for first analysis
constantinpape Nov 7, 2024
7be9ee8
2D seg with mask
SarahMuth Nov 11, 2024
b1bef7e
Merge branch 'analysis' of https://github.com/computational-cell-anal…
SarahMuth Nov 11, 2024
f85e445
spatial distribution analysis
SarahMuth Nov 11, 2024
8ef16bc
intersection between compartment boundary and AZ segmentaiton
SarahMuth Nov 12, 2024
e625ef7
Merge branch 'main' of https://github.com/computational-cell-analytic…
SarahMuth Nov 12, 2024
09f6c84
Update compartment postprocessing
constantinpape Nov 12, 2024
d7dbb39
Merge branch 'more-comp-seg-updates' of https://github.com/computatio…
SarahMuth Nov 12, 2024
f893d23
updating data analysis on smaller details
SarahMuth Nov 13, 2024
08c56b9
minor updates data analysis
SarahMuth Nov 13, 2024
36d834f
Implement inner ear analysis WIP
constantinpape Nov 14, 2024
49d1b7c
calculation of AZ area
SarahMuth Nov 14, 2024
8a515d1
corrected radius factor
SarahMuth Nov 14, 2024
0f40d3c
Update inner ear analysis
constantinpape Nov 15, 2024
ad4741b
Update inner ear analysis
constantinpape Nov 17, 2024
305a80b
Updates to inner ear training and eval
constantinpape Nov 17, 2024
903e59e
Update inner ear analysis
constantinpape Nov 18, 2024
b1449d2
minor changes
SarahMuth Nov 19, 2024
0b7884d
Merge branch 'main' of https://github.com/computational-cell-analytic…
constantinpape Nov 19, 2024
186c92d
Update inner ear analysis scripts
constantinpape Nov 20, 2024
186df5b
Merge branch 'more-inner-ear-analysis' of https://github.com/computat…
constantinpape Nov 20, 2024
2ccf340
Add script to extract vesicle diameters for inner ear data
constantinpape Nov 20, 2024
5feff6a
Update active zone analysis for SNAP/MUNC data
constantinpape Nov 21, 2024
9b8c7a2
Add more inner ear analysis code
constantinpape Nov 21, 2024
db89b44
evaluation of AZ seg
SarahMuth Nov 23, 2024
51165a5
Fix issues with the segmentation export to IMOD
constantinpape Nov 23, 2024
aa5d78e
clean up
SarahMuth Nov 23, 2024
20e429b
clean up
SarahMuth Nov 23, 2024
19f618e
clean up
SarahMuth Nov 23, 2024
cb693b1
Update data summaries
constantinpape Nov 24, 2024
a0c31a8
Fix issue in data aggregation
constantinpape Nov 24, 2024
93a66c1
Update data summary
constantinpape Nov 24, 2024
e0dfda6
Merge branch 'main' into more-inner-ear-analysis
constantinpape Nov 24, 2024
59a38db
Update all measurements for the inner ear analysis
constantinpape Nov 24, 2024
9728951
Update vesicle diameter analysis
constantinpape Nov 24, 2024
84d3ec7
Merge branch 'more-inner-ear-analysis' of https://github.com/computat…
SarahMuth Nov 25, 2024
622da1e
update AZ evaluation
SarahMuth Nov 27, 2024
686b018
erosion dilation filtering of AZ
SarahMuth Nov 28, 2024
6b54e4a
stuff for revision
SarahMuth Mar 31, 2025
7d675ab
everything after 1st revision relating to training, inference, postpr…
SarahMuth May 22, 2025
f052b98
minor things
SarahMuth May 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update inner ear analysis
  • Loading branch information
constantinpape committed Nov 17, 2024
commit ad4741b72b3a36041d341f55a6bf0269c20ed3d5
2 changes: 2 additions & 0 deletions scripts/inner_ear/analysis/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
panels/
*.zip
84 changes: 79 additions & 5 deletions scripts/inner_ear/analysis/analyze_distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,91 @@


def for_tomos_with_annotation():
manual_assignments, automatic_assignments = get_measurements_with_annotation()
breakpoint()
manual_assignments, semi_automatic_assignments, automatic_assignments = get_measurements_with_annotation()

manual_distances = manual_assignments[
["pool", "ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]
]
manual_distances["approach"] = ["manual"] * len(manual_distances)

# def for_all_tomos():
# automatic_assignments = get_all_measurements()
semi_automatic_distances = semi_automatic_assignments[
["pool", "ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]
]
semi_automatic_distances["approach"] = ["semi_automatic"] * len(semi_automatic_distances)

automatic_distances = automatic_assignments[
["pool", "ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]
]
automatic_distances["approach"] = ["automatic"] * len(automatic_distances)

distances = pd.concat([manual_distances, semi_automatic_distances, automatic_distances])
distances.to_excel("./results/distances_with_manual_annotations.xlsx", index=False)

pools = pd.unique(distances["pool"])
dist_cols = ["ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]

fig, axes = plt.subplots(3, 3)

# multiple = "stack"
multiple = "layer"

structures = ["Ribbon", "PD", "Boundary"]
for i, pool in enumerate(pools):
pool_distances = distances[distances["pool"] == pool]
for j, dist_col in enumerate(dist_cols):
ax = axes[i, j]
ax.set_title(f"{pool} to {structures[j]}")
sns.histplot(
data=pool_distances, x=dist_col, hue="approach", multiple=multiple, kde=False, ax=ax
)
ax.set_xlabel("distance [nm]")

fig.tight_layout()
plt.show()


def for_all_tomos():
semi_automatic_assignments, automatic_assignments = get_all_measurements()

semi_automatic_distances = semi_automatic_assignments[
["pool", "ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]
]
semi_automatic_distances["approach"] = ["semi_automatic"] * len(semi_automatic_distances)

automatic_distances = automatic_assignments[
["pool", "ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]
]
automatic_distances["approach"] = ["automatic"] * len(automatic_distances)

distances = pd.concat([semi_automatic_distances, automatic_distances])
distances.to_excel("./results/distances_all_tomograms.xlsx", index=False)

pools = pd.unique(distances["pool"])
dist_cols = ["ribbon_distance [nm]", "pd_distance [nm]", "boundary_distance [nm]"]

fig, axes = plt.subplots(3, 3)

# multiple = "stack"
multiple = "layer"

structures = ["Ribbon", "PD", "Boundary"]
for i, pool in enumerate(pools):
pool_distances = distances[distances["pool"] == pool]
for j, dist_col in enumerate(dist_cols):
ax = axes[i, j]
ax.set_title(f"{pool} to {structures[j]}")
sns.histplot(
data=pool_distances, x=dist_col, hue="approach", multiple=multiple, kde=False, ax=ax
)
ax.set_xlabel("distance [nm]")

fig.tight_layout()
plt.show()


def main():
for_tomos_with_annotation()
# for_all_tomos()
for_all_tomos()


if __name__ == "__main__":
Expand Down
32 changes: 15 additions & 17 deletions scripts/inner_ear/analysis/analyze_vesicle_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,63 +34,61 @@ def plot_pools(data, errors):
plt.show()


# TODO use the actual results without vesicle post-processing.
def for_tomos_with_annotation():
manual_assignments, automatic_assignments = get_measurements_with_annotation()
manual_assignments, semi_automatic_assignments, automatic_assignments = get_measurements_with_annotation()

manual_counts = manual_assignments.groupby(["tomogram", "pool"]).size().unstack(fill_value=0)
semi_automatic_counts = semi_automatic_assignments.groupby(["tomogram", "pool"]).size().unstack(fill_value=0)
automatic_counts = automatic_assignments.groupby(["tomogram", "pool"]).size().unstack(fill_value=0)

manual_stats = manual_counts.agg(["mean", "std"]).transpose().reset_index()
semi_automatic_stats = semi_automatic_counts.agg(["mean", "std"]).transpose().reset_index()
automatic_stats = automatic_counts.agg(["mean", "std"]).transpose().reset_index()

data = pd.DataFrame({
"Pool": manual_stats["pool"],
"Manual": manual_stats["mean"],
"Semi-automatic": automatic_stats["mean"],
"Semi-automatic": semi_automatic_stats["mean"],
"Automatic": automatic_stats["mean"],
"Manual": manual_stats["mean"],
})
errors = pd.DataFrame({
"Pool": manual_stats["pool"],
"Manual": manual_stats["std"],
"Semi-automatic": automatic_stats["std"],
"Semi-automatic": semi_automatic_stats["std"],
"Automatic": automatic_stats["std"],
"Manual": manual_stats["std"],
})

plot_pools(data, errors)

output_path = "./vesicle_pools_small.xlsx"
output_path = "./results/vesicle_pools_with_manual_annotations.xlsx"
data.to_excel(output_path, index=False, sheet_name="Average")
with pd.ExcelWriter(output_path, engine="openpyxl", mode="a") as writer:
errors.to_excel(writer, sheet_name="StandardDeviation", index=False)


# TODO use the actual results without vesicle post-processing.
def for_all_tomos():

automatic_assignments = get_all_measurements()
# TODO double check why this number is so different! (64 vs. 81)
# tomos = pd.unique(automatic_assignments["tomogram"])
# print(len(tomos), n_tomos)
# assert len(tomos) == n_tomos
semi_automatic_assignments, automatic_assignments = get_all_measurements()

automatic_counts = automatic_assignments.groupby(["tomogram", "pool"]).size().unstack(fill_value=0)
automatic_stats = automatic_counts.agg(["mean", "std"]).transpose().reset_index()

semi_automatic_counts = semi_automatic_assignments.groupby(["tomogram", "pool"]).size().unstack(fill_value=0)
semi_automatic_stats = semi_automatic_counts.agg(["mean", "std"]).transpose().reset_index()

data = pd.DataFrame({
"Pool": automatic_stats["pool"],
"Semi-automatic": automatic_stats["mean"],
"Semi-automatic": semi_automatic_stats["mean"],
"Automatic": automatic_stats["mean"],
})
errors = pd.DataFrame({
"Pool": automatic_stats["pool"],
"Semi-automatic": automatic_stats["std"],
"Semi-automatic": semi_automatic_stats["std"],
"Automatic": automatic_stats["std"],
})

plot_pools(data, errors)

output_path = "./vesicle_pools_large.xlsx"
output_path = "./results/vesicle_pools_all_tomograms.xlsx"
data.to_excel(output_path, index=False, sheet_name="Average")
with pd.ExcelWriter(output_path, engine="openpyxl", mode="a") as writer:
errors.to_excel(writer, sheet_name="StandardDeviation", index=False)
Expand Down
69 changes: 69 additions & 0 deletions scripts/inner_ear/analysis/combine_fully_automatic_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import os
import sys

import pandas as pd

sys.path.append("..")
sys.path.append("../processing")


def combine_fully_auto_results(table, data_root, output_path):
from combine_measurements import combine_results

val_table_path = os.path.join(data_root, "Electron-Microscopy-Susi", "Validierungs-Tabelle-v3.xlsx")
val_table = pd.read_excel(val_table_path)

results = {}
for _, row in table.iterrows():
folder = row["Local Path"]
if folder == "":
continue

row_selection = (val_table.Bedingung == row.Bedingung) &\
(val_table.Maus == row.Maus) &\
(val_table["Ribbon-Orientierung"] == row["Ribbon-Orientierung"]) &\
(val_table["OwnCloud-Unterordner"] == row["OwnCloud-Unterordner"])
complete_vals = val_table[row_selection]["Fertig!"].values
is_complete = (complete_vals == "ja").all()
if not is_complete:
continue

micro = row["EM alt vs. Neu"]

tomo_name = os.path.relpath(folder, os.path.join(data_root, "Electron-Microscopy-Susi/Analyse"))
tab_name = "measurements_uncorrected_assignments.xlsx"
res_path = os.path.join(folder, "korrektur", tab_name)
if not os.path.exists(res_path):
res_path = os.path.join(folder, "Korrektur", tab_name)
assert os.path.exists(res_path), res_path
results[tomo_name] = (res_path, "alt" if micro == "beides" else micro)

if micro == "beides":
micro = "neu"

new_root = os.path.join(folder, "neues EM")
if not os.path.exists(new_root):
new_root = os.path.join(folder, "Tomo neues EM")
assert os.path.exists(new_root)

res_path = os.path.join(new_root, "korrektur", "measurements.xlsx")
if not os.path.exists(res_path):
res_path = os.path.join(new_root, "Korrektur", "measurements.xlsx")
assert os.path.exists(res_path), res_path
results[tomo_name] = (res_path, "alt" if micro == "beides" else micro)

combine_results(results, output_path, sheet_name="vesicles")


def main():
from parse_table import parse_table, get_data_root

data_root = get_data_root()
table_path = os.path.join(data_root, "Electron-Microscopy-Susi", "Übersicht.xlsx")
table = parse_table(table_path, data_root)

res_path = "../results/fully_automatic_analysis_results.xlsx"
combine_fully_auto_results(table, data_root, output_path=res_path)


main()
40 changes: 34 additions & 6 deletions scripts/inner_ear/analysis/common.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import sys

import pandas as pd

sys.path.append("../processing")
Expand All @@ -13,23 +14,35 @@ def get_manual_assignments():
return results


def get_automatic_assignments(tomograms):
def get_semi_automatic_assignments(tomograms):
result_path = "../results/20240917_1/automatic_analysis_results.xlsx"
results = pd.read_excel(result_path)
results = results[results["tomogram"].isin(tomograms)]
return results


def get_automatic_assignments(tomograms):
result_path = "../results/fully_automatic_analysis_results.xlsx"
results = pd.read_excel(result_path)
results = results[results["tomogram"].isin(tomograms)]
return results


def get_measurements_with_annotation():
manual_assignments = get_manual_assignments()
manual_tomograms = pd.unique(manual_assignments["tomogram"])
automatic_assignments = get_automatic_assignments(manual_tomograms)
semi_automatic_assignments = get_semi_automatic_assignments(manual_tomograms)

tomograms = pd.unique(automatic_assignments["tomogram"])
tomograms = pd.unique(semi_automatic_assignments["tomogram"])
manual_assignments = manual_assignments[manual_assignments["tomogram"].isin(tomograms)]
assert len(pd.unique(manual_assignments["tomogram"])) == len(pd.unique(automatic_assignments["tomogram"]))
assert len(pd.unique(manual_assignments["tomogram"])) == len(pd.unique(semi_automatic_assignments["tomogram"]))

return manual_assignments, automatic_assignments
automatic_assignments = get_automatic_assignments(tomograms)
filtered_tomograms = pd.unique(manual_assignments["tomogram"])
assert len(filtered_tomograms) == len(pd.unique(automatic_assignments["tomogram"]))

print("Tomograms with manual annotations:", len(filtered_tomograms))
return manual_assignments, semi_automatic_assignments, automatic_assignments


def get_all_measurements():
Expand All @@ -39,6 +52,7 @@ def get_all_measurements():

val_table = val_table[val_table["Kommentar 27-10-24"] == "passt"]
n_tomos = len(val_table)
print("All tomograms:", n_tomos)
assert n_tomos > 0
tomo_names = []
for _, row in val_table.iterrows():
Expand All @@ -49,5 +63,19 @@ def get_all_measurements():
)
tomo_names.append(name)

semi_automatic_assignments = get_semi_automatic_assignments(tomo_names)
filtered_tomo_names = pd.unique(semi_automatic_assignments["tomogram"]).tolist()

automatic_assignments = get_automatic_assignments(tomo_names)
return automatic_assignments
assert len(filtered_tomo_names) == len(pd.unique(automatic_assignments["tomogram"]))

return semi_automatic_assignments, automatic_assignments


def main():
get_measurements_with_annotation()
get_all_measurements()


if __name__ == "__main__":
main()