canns 0.14.2__py3-none-any.whl → 0.15.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. canns/analyzer/data/asa/__init__.py +77 -21
  2. canns/analyzer/data/asa/coho.py +97 -0
  3. canns/analyzer/data/asa/cohomap.py +408 -0
  4. canns/analyzer/data/asa/cohomap_scatter.py +10 -0
  5. canns/analyzer/data/asa/cohomap_vectors.py +311 -0
  6. canns/analyzer/data/asa/cohospace.py +173 -1153
  7. canns/analyzer/data/asa/cohospace_phase_centers.py +137 -0
  8. canns/analyzer/data/asa/cohospace_scatter.py +1220 -0
  9. canns/analyzer/data/asa/embedding.py +3 -4
  10. canns/analyzer/data/asa/plotting.py +4 -4
  11. canns/analyzer/data/cell_classification/__init__.py +10 -0
  12. canns/analyzer/data/cell_classification/core/__init__.py +4 -0
  13. canns/analyzer/data/cell_classification/core/btn.py +272 -0
  14. canns/analyzer/data/cell_classification/visualization/__init__.py +3 -0
  15. canns/analyzer/data/cell_classification/visualization/btn_plots.py +258 -0
  16. canns/analyzer/visualization/__init__.py +2 -0
  17. canns/analyzer/visualization/core/config.py +20 -0
  18. canns/analyzer/visualization/theta_sweep_plots.py +142 -0
  19. canns/pipeline/asa/runner.py +19 -19
  20. canns/pipeline/asa_gui/__init__.py +5 -3
  21. canns/pipeline/asa_gui/analysis_modes/pathcompare_mode.py +32 -4
  22. canns/pipeline/asa_gui/core/runner.py +23 -23
  23. canns/pipeline/asa_gui/views/pages/preprocess_page.py +250 -8
  24. {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/METADATA +2 -1
  25. {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/RECORD +28 -20
  26. {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/WHEEL +0 -0
  27. {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/entry_points.txt +0 -0
  28. {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,137 @@
1
+ """Phase-center utilities for CohoSpace (skewed coordinates)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+
11
+ from ...visualization.core import PlotConfig, finalize_figure
12
+ from .cohospace_scatter import skew_transform_torus_scatter
13
+
14
+
15
+ def _ensure_plot_config(
16
+ config: PlotConfig | None,
17
+ factory,
18
+ *args,
19
+ **defaults,
20
+ ) -> PlotConfig:
21
+ if config is None:
22
+ return factory(*args, **defaults)
23
+ return config
24
+
25
+
26
+ def _ensure_parent_dir(save_path: str | None) -> None:
27
+ if save_path:
28
+ parent = os.path.dirname(save_path)
29
+ if parent:
30
+ os.makedirs(parent, exist_ok=True)
31
+
32
+
33
+ def cohospace_phase_centers(cohospace_result: dict[str, Any]) -> dict[str, Any]:
34
+ """
35
+ Compute per-neuron CohoSpace phase centers and their skewed coordinates.
36
+
37
+ Input
38
+ -----
39
+ cohospace_result : dict
40
+ Output from `data.cohospace(...)` (must include `centers`).
41
+ """
42
+ centers = np.asarray(cohospace_result["centers"], dtype=float) % (2 * np.pi)
43
+ centers_skew = skew_transform_torus_scatter(centers)
44
+ return {
45
+ "centers": centers,
46
+ "centers_skew": centers_skew,
47
+ }
48
+
49
+
50
+ def plot_cohospace_phase_centers(
51
+ cohospace_result: dict[str, Any],
52
+ *,
53
+ neuron_id: int | None = None,
54
+ show_all: bool = False,
55
+ config: PlotConfig | None = None,
56
+ save_path: str | None = None,
57
+ show: bool = False,
58
+ figsize: tuple[int, int] = (5, 5),
59
+ all_color: str = "tab:blue",
60
+ highlight_color: str = "tab:red",
61
+ alpha: float = 0.7,
62
+ s: int = 12,
63
+ ) -> plt.Figure:
64
+ """
65
+ Plot CohoSpace phase centers on the skewed torus domain.
66
+
67
+ If neuron_id is None, plot all neurons. If neuron_id is provided, show_all controls
68
+ whether all neurons are drawn lightly or only the selected neuron is shown.
69
+ """
70
+ centers_result = cohospace_phase_centers(cohospace_result)
71
+ centers_skew = centers_result["centers_skew"]
72
+ num_neurons = centers_skew.shape[0]
73
+
74
+ if neuron_id is not None and (neuron_id < 0 or neuron_id >= num_neurons):
75
+ raise ValueError(f"neuron_id out of range: {neuron_id}")
76
+
77
+ title = "CohoSpace phase centers (skewed)"
78
+ if neuron_id is not None and not show_all:
79
+ title = f"CohoSpace phase center (neuron {neuron_id}, skewed)"
80
+ elif neuron_id is not None and show_all:
81
+ title = f"CohoSpace phase centers (all + neuron {neuron_id}, skewed)"
82
+
83
+ config = _ensure_plot_config(
84
+ config,
85
+ PlotConfig.for_static_plot,
86
+ title=title,
87
+ xlabel=r"$\theta_1 + \frac{1}{2}\theta_2$",
88
+ ylabel=r"$\frac{\sqrt{3}}{2}\theta_2$",
89
+ figsize=figsize,
90
+ save_path=save_path,
91
+ show=show,
92
+ )
93
+
94
+ fig, ax = plt.subplots(figsize=config.figsize)
95
+
96
+ # fundamental domain parallelogram
97
+ e1 = np.array([2 * np.pi, 0.0])
98
+ e2 = np.array([np.pi, np.sqrt(3) * np.pi])
99
+ poly = np.vstack([[0.0, 0.0], e1, e1 + e2, e2, [0.0, 0.0]])
100
+ ax.plot(poly[:, 0], poly[:, 1], lw=1.2, color="0.35")
101
+
102
+ if neuron_id is None:
103
+ ax.scatter(centers_skew[:, 0], centers_skew[:, 1], s=s, alpha=alpha, color=all_color)
104
+ else:
105
+ if show_all:
106
+ ax.scatter(
107
+ centers_skew[:, 0],
108
+ centers_skew[:, 1],
109
+ s=max(4, s - 4),
110
+ alpha=0.25,
111
+ color=all_color,
112
+ )
113
+ ax.scatter(
114
+ centers_skew[neuron_id, 0],
115
+ centers_skew[neuron_id, 1],
116
+ s=max(10, s + 6),
117
+ alpha=0.9,
118
+ color=highlight_color,
119
+ )
120
+
121
+ base = np.vstack([[0.0, 0.0], e1, e2, e1 + e2])
122
+ xmin, ymin = base.min(axis=0)
123
+ xmax, ymax = base.max(axis=0)
124
+ padx = 0.03 * (xmax - xmin)
125
+ pady = 0.03 * (ymax - ymin)
126
+ ax.set_xlim(xmin - padx, xmax + padx)
127
+ ax.set_ylim(ymin - pady, ymax + pady)
128
+ ax.set_aspect("equal")
129
+ ax.set_xlabel(config.xlabel)
130
+ ax.set_ylabel(config.ylabel)
131
+ ax.set_title(config.title)
132
+ ax.set_xticks([])
133
+ ax.set_yticks([])
134
+
135
+ _ensure_parent_dir(config.save_path)
136
+ finalize_figure(fig, config)
137
+ return fig