Skip to content

Commit 433b913

Browse files
Implement SGN density analysis
1 parent 478bc0f commit 433b913

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import os
2+
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
import pandas as pd
6+
7+
from flamingo_tools.s3_utils import create_s3_target, BUCKET_NAME
8+
9+
10+
def _gaussian_kernel1d(sigma_pix, truncate=4.0):
11+
r = int(truncate * sigma_pix + 0.5)
12+
x = np.arange(-r, r + 1, dtype=float)
13+
k = np.exp(-(x**2) / (2 * sigma_pix**2))
14+
k /= k.sum()
15+
return k
16+
17+
18+
def density_1d_simple(x, window):
19+
x = np.asarray(x, dtype=float)
20+
xmin, xmax = x.min(), x.max()
21+
22+
# Fixed grid (kept internal for simplicity)
23+
nbins = 256
24+
edges = np.linspace(xmin, xmax, nbins + 1)
25+
centers = 0.5 * (edges[:-1] + edges[1:])
26+
dx = edges[1] - edges[0]
27+
28+
# Bin counts, smooth with Gaussian, convert to density
29+
counts, _ = np.histogram(x, bins=edges, density=False)
30+
sigma_pix = max(window / dx, 1e-9)
31+
k = _gaussian_kernel1d(sigma_pix)
32+
counts_smooth = np.convolve(counts, k, mode="same")
33+
density = counts_smooth / dx
34+
35+
return centers, density
36+
37+
38+
def open_tsv(fs, path):
39+
s3_path = os.path.join(BUCKET_NAME, path)
40+
with fs.open(s3_path, "r") as f:
41+
table = pd.read_csv(f, sep="\t")
42+
return table
43+
44+
45+
def analyze_cochlea(cochlea, plot=False):
46+
fs = create_s3_target()
47+
seg_name = "SGN_v2"
48+
49+
table_path = f"tables/{seg_name}/default.tsv"
50+
table = open_tsv(fs, os.path.join(cochlea, table_path))
51+
52+
component_ids = [1]
53+
table = table[table.component_labels.isin(component_ids)]
54+
55+
window_size = 200.0
56+
grid, density = density_1d_simple(table["length[µm]"], window=window_size) # window in same units as x
57+
58+
if plot:
59+
plt.figure(figsize=(6, 3))
60+
plt.plot(grid, density, lw=2)
61+
plt.xlabel("Length [µm]")
62+
plt.ylabel("Density [SGN/µm]")
63+
plt.tight_layout()
64+
plt.show()
65+
else:
66+
return grid, density
67+
68+
69+
def check_implementation():
70+
cochlea = "G_EK_000049_L"
71+
analyze_cochlea(cochlea, plot=True)
72+
73+
74+
def compare_gerbil_cochleae():
75+
# We need the tonotopic mapping for G_EK_000233_L
76+
# cochleae = ["G_EK_000233_L", "G_EK_000049_L", "G_EK_000049_R"]
77+
cochleae = ["G_EK_000049_L", "G_EK_000049_R"]
78+
79+
plt.figure(figsize=(6, 3))
80+
for cochlea in cochleae:
81+
grid, density = analyze_cochlea(cochlea, plot=False)
82+
plt.plot(grid, density, lw=2, label=cochlea)
83+
84+
plt.xlabel("Length [µm]")
85+
plt.ylabel("Density [SGN/µm]")
86+
plt.legend()
87+
plt.tight_layout()
88+
plt.show()
89+
90+
91+
def main():
92+
# check_implementation()
93+
compare_gerbil_cochleae()
94+
95+
96+
if __name__ == "__main__":
97+
main()

0 commit comments

Comments
 (0)