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.
- canns/analyzer/data/asa/__init__.py +77 -21
- canns/analyzer/data/asa/coho.py +97 -0
- canns/analyzer/data/asa/cohomap.py +408 -0
- canns/analyzer/data/asa/cohomap_scatter.py +10 -0
- canns/analyzer/data/asa/cohomap_vectors.py +311 -0
- canns/analyzer/data/asa/cohospace.py +173 -1153
- canns/analyzer/data/asa/cohospace_phase_centers.py +137 -0
- canns/analyzer/data/asa/cohospace_scatter.py +1220 -0
- canns/analyzer/data/asa/embedding.py +3 -4
- canns/analyzer/data/asa/plotting.py +4 -4
- canns/analyzer/data/cell_classification/__init__.py +10 -0
- canns/analyzer/data/cell_classification/core/__init__.py +4 -0
- canns/analyzer/data/cell_classification/core/btn.py +272 -0
- canns/analyzer/data/cell_classification/visualization/__init__.py +3 -0
- canns/analyzer/data/cell_classification/visualization/btn_plots.py +258 -0
- canns/analyzer/visualization/__init__.py +2 -0
- canns/analyzer/visualization/core/config.py +20 -0
- canns/analyzer/visualization/theta_sweep_plots.py +142 -0
- canns/pipeline/asa/runner.py +19 -19
- canns/pipeline/asa_gui/__init__.py +5 -3
- canns/pipeline/asa_gui/analysis_modes/pathcompare_mode.py +32 -4
- canns/pipeline/asa_gui/core/runner.py +23 -23
- canns/pipeline/asa_gui/views/pages/preprocess_page.py +250 -8
- {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/METADATA +2 -1
- {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/RECORD +28 -20
- {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/WHEEL +0 -0
- {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/entry_points.txt +0 -0
- {canns-0.14.2.dist-info → canns-0.15.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
import numpy as np
|
|
7
8
|
from PySide6.QtCore import QSettings, Qt, Signal
|
|
8
9
|
from PySide6.QtGui import QColor
|
|
9
10
|
from PySide6.QtWidgets import (
|
|
@@ -15,6 +16,7 @@ from PySide6.QtWidgets import (
|
|
|
15
16
|
QGroupBox,
|
|
16
17
|
QHBoxLayout,
|
|
17
18
|
QLabel,
|
|
19
|
+
QLineEdit,
|
|
18
20
|
QProgressBar,
|
|
19
21
|
QPushButton,
|
|
20
22
|
QSpinBox,
|
|
@@ -86,6 +88,12 @@ class PreprocessPage(QWidget):
|
|
|
86
88
|
self.preset.addItems(["grid", "hd", "none"])
|
|
87
89
|
self.preset.setToolTip("Preset hints apply to analysis mode defaults.")
|
|
88
90
|
|
|
91
|
+
self.input_source = PopupComboBox()
|
|
92
|
+
self.input_source.addItem("Local file", userData="local")
|
|
93
|
+
self.input_source.addItem("CANNs dataset", userData="dataset")
|
|
94
|
+
self.input_source.addItem("URL", userData="url")
|
|
95
|
+
self.input_source.currentIndexChanged.connect(self._toggle_input_source)
|
|
96
|
+
|
|
89
97
|
self.label_mode = QLabel("Mode")
|
|
90
98
|
top_row.addWidget(self.label_mode)
|
|
91
99
|
top_row.addWidget(self.input_mode)
|
|
@@ -93,6 +101,10 @@ class PreprocessPage(QWidget):
|
|
|
93
101
|
self.label_preset = QLabel("Preset")
|
|
94
102
|
top_row.addWidget(self.label_preset)
|
|
95
103
|
top_row.addWidget(self.preset)
|
|
104
|
+
top_row.addSpacing(16)
|
|
105
|
+
self.label_source = QLabel("Source")
|
|
106
|
+
top_row.addWidget(self.label_source)
|
|
107
|
+
top_row.addWidget(self.input_source)
|
|
96
108
|
top_row.addStretch(1)
|
|
97
109
|
input_layout.addLayout(top_row)
|
|
98
110
|
|
|
@@ -126,6 +138,46 @@ class PreprocessPage(QWidget):
|
|
|
126
138
|
input_layout.addLayout(neuron_row)
|
|
127
139
|
input_layout.addLayout(traj_row)
|
|
128
140
|
|
|
141
|
+
self.dataset_group = QGroupBox("Dataset")
|
|
142
|
+
self.dataset_group.setObjectName("card")
|
|
143
|
+
dataset_form = QFormLayout(self.dataset_group)
|
|
144
|
+
|
|
145
|
+
self.dataset_key = PopupComboBox()
|
|
146
|
+
self.dataset_key.addItem("grid_1", userData="grid_1")
|
|
147
|
+
self.dataset_key.addItem("grid_2", userData="grid_2")
|
|
148
|
+
self.dataset_key.addItem("roi_data", userData="roi_data")
|
|
149
|
+
self.dataset_key.addItem("left_right_data_of", userData="left_right_data_of")
|
|
150
|
+
self.dataset_key.currentIndexChanged.connect(self._update_dataset_hint)
|
|
151
|
+
|
|
152
|
+
self.dataset_session = QLineEdit()
|
|
153
|
+
self.dataset_session.setPlaceholderText("e.g. 26034_3")
|
|
154
|
+
|
|
155
|
+
self.dataset_filename = QLineEdit()
|
|
156
|
+
self.dataset_filename.setPlaceholderText("e.g. 26034_3_ASA_full.npz")
|
|
157
|
+
|
|
158
|
+
self.dataset_url = QLineEdit()
|
|
159
|
+
self.dataset_url.setPlaceholderText("https://.../data.npz")
|
|
160
|
+
|
|
161
|
+
self.dataset_hint = QLabel("")
|
|
162
|
+
self.dataset_hint.setObjectName("muted")
|
|
163
|
+
self.dataset_hint.setWordWrap(True)
|
|
164
|
+
|
|
165
|
+
dataset_form.addRow("Dataset", self.dataset_key)
|
|
166
|
+
self.label_dataset = dataset_form.labelForField(self.dataset_key)
|
|
167
|
+
dataset_form.addRow("Session id", self.dataset_session)
|
|
168
|
+
self.label_session = dataset_form.labelForField(self.dataset_session)
|
|
169
|
+
dataset_form.addRow("Filename", self.dataset_filename)
|
|
170
|
+
self.label_filename = dataset_form.labelForField(self.dataset_filename)
|
|
171
|
+
url_row = QWidget()
|
|
172
|
+
url_layout = QHBoxLayout(url_row)
|
|
173
|
+
url_layout.setContentsMargins(0, 0, 0, 0)
|
|
174
|
+
url_layout.addWidget(self.dataset_url, 1)
|
|
175
|
+
dataset_form.addRow("URL", url_row)
|
|
176
|
+
self.label_url = dataset_form.labelForField(self.dataset_url)
|
|
177
|
+
dataset_form.addRow(self.dataset_hint)
|
|
178
|
+
|
|
179
|
+
input_layout.addWidget(self.dataset_group)
|
|
180
|
+
|
|
129
181
|
top_layout.addWidget(input_group)
|
|
130
182
|
|
|
131
183
|
# Preprocess group
|
|
@@ -244,6 +296,8 @@ class PreprocessPage(QWidget):
|
|
|
244
296
|
self.asa_browse.clicked.connect(self._update_run_enabled)
|
|
245
297
|
|
|
246
298
|
self._toggle_input_mode()
|
|
299
|
+
self._toggle_input_source()
|
|
300
|
+
self._update_dataset_hint()
|
|
247
301
|
self._toggle_embed_params()
|
|
248
302
|
self._update_run_enabled()
|
|
249
303
|
self._apply_card_effects([input_group, preprocess_group, preclass_group])
|
|
@@ -270,6 +324,7 @@ class PreprocessPage(QWidget):
|
|
|
270
324
|
|
|
271
325
|
self.label_mode.setText("模式" if is_zh else "Mode")
|
|
272
326
|
self.label_preset.setText("预设" if is_zh else "Preset")
|
|
327
|
+
self.label_source.setText("来源" if is_zh else "Source")
|
|
273
328
|
if self.label_method is not None:
|
|
274
329
|
self.label_method.setText("方法" if is_zh else "Method")
|
|
275
330
|
if self.label_preclass is not None:
|
|
@@ -317,6 +372,32 @@ class PreprocessPage(QWidget):
|
|
|
317
372
|
self.stop_btn.setText("停止" if is_zh else "Stop")
|
|
318
373
|
self.logs_label.setText("日志" if is_zh else "Logs")
|
|
319
374
|
|
|
375
|
+
self.dataset_group.setTitle("数据集" if is_zh else "Dataset")
|
|
376
|
+
if self.label_dataset is not None:
|
|
377
|
+
self.label_dataset.setText("数据集" if is_zh else "Dataset")
|
|
378
|
+
if self.label_session is not None:
|
|
379
|
+
self.label_session.setText("Session id" if not is_zh else "会话 id")
|
|
380
|
+
if self.label_filename is not None:
|
|
381
|
+
self.label_filename.setText("Filename" if not is_zh else "文件名")
|
|
382
|
+
if self.label_url is not None:
|
|
383
|
+
self.label_url.setText("URL")
|
|
384
|
+
|
|
385
|
+
self.input_source.setToolTip(
|
|
386
|
+
"选择本地文件、内置数据集或 URL"
|
|
387
|
+
if is_zh
|
|
388
|
+
else "Choose local file, built-in dataset, or URL."
|
|
389
|
+
)
|
|
390
|
+
self.dataset_key.setToolTip("选择内置数据集" if is_zh else "Select a built-in dataset.")
|
|
391
|
+
self.dataset_session.setToolTip(
|
|
392
|
+
"Left-Right 数据集的会话 id。" if is_zh else "Session id for Left-Right dataset."
|
|
393
|
+
)
|
|
394
|
+
self.dataset_filename.setToolTip(
|
|
395
|
+
"Left-Right 数据集文件名。" if is_zh else "Filename within Left-Right dataset."
|
|
396
|
+
)
|
|
397
|
+
self.dataset_url.setToolTip(
|
|
398
|
+
"直接加载 .npz 链接。" if is_zh else "Load a .npz URL directly."
|
|
399
|
+
)
|
|
400
|
+
|
|
320
401
|
self.input_mode.setToolTip(
|
|
321
402
|
"仅支持 ASA .npz 输入" if is_zh else "Only ASA .npz input is supported in this GUI."
|
|
322
403
|
)
|
|
@@ -326,7 +407,9 @@ class PreprocessPage(QWidget):
|
|
|
326
407
|
else "Embedding builds a dense spike matrix for TDA/FR."
|
|
327
408
|
)
|
|
328
409
|
self.embed_res.setToolTip(
|
|
329
|
-
"时间分箱分辨率(与 t 单位一致)。"
|
|
410
|
+
"时间分箱分辨率(与 t 单位一致)。"
|
|
411
|
+
if is_zh
|
|
412
|
+
else "Time bin resolution (same unit as t)."
|
|
330
413
|
)
|
|
331
414
|
self.embed_dt.setToolTip(
|
|
332
415
|
"时间步长(与 t 单位一致)。" if is_zh else "Time step (same unit as t)."
|
|
@@ -341,11 +424,18 @@ class PreprocessPage(QWidget):
|
|
|
341
424
|
else "Remove low-speed samples (common for grid data)."
|
|
342
425
|
)
|
|
343
426
|
self.embed_min_speed.setToolTip(
|
|
344
|
-
"速度阈值(与 t/x/y 单位一致)。"
|
|
345
|
-
if is_zh
|
|
346
|
-
else "Speed threshold (same unit as t/x/y)."
|
|
427
|
+
"速度阈值(与 t/x/y 单位一致)。" if is_zh else "Speed threshold (same unit as t/x/y)."
|
|
347
428
|
)
|
|
348
429
|
|
|
430
|
+
self.dataset_session.setPlaceholderText("例如 26034_3" if is_zh else "e.g. 26034_3")
|
|
431
|
+
self.dataset_filename.setPlaceholderText(
|
|
432
|
+
"例如 26034_3_ASA_full.npz" if is_zh else "e.g. 26034_3_ASA_full.npz"
|
|
433
|
+
)
|
|
434
|
+
self.dataset_url.setPlaceholderText(
|
|
435
|
+
"https://.../data.npz" if not is_zh else "https://.../data.npz"
|
|
436
|
+
)
|
|
437
|
+
self._update_dataset_hint()
|
|
438
|
+
|
|
349
439
|
def _show_help(self) -> None:
|
|
350
440
|
lang = str(QSettings("canns", "asa_gui").value("lang", "en"))
|
|
351
441
|
title = (
|
|
@@ -386,6 +476,61 @@ class PreprocessPage(QWidget):
|
|
|
386
476
|
self.traj_zone.setVisible(not use_asa)
|
|
387
477
|
self.traj_browse.setVisible(not use_asa)
|
|
388
478
|
|
|
479
|
+
def _toggle_input_source(self) -> None:
|
|
480
|
+
source = self.input_source.currentData() or "local"
|
|
481
|
+
use_local = source == "local"
|
|
482
|
+
self.asa_zone.setVisible(use_local)
|
|
483
|
+
self.asa_browse.setVisible(use_local)
|
|
484
|
+
self.asa_hint.setVisible(use_local)
|
|
485
|
+
self.dataset_group.setVisible(not use_local)
|
|
486
|
+
self._update_dataset_hint()
|
|
487
|
+
self._update_run_enabled()
|
|
488
|
+
|
|
489
|
+
def _update_dataset_hint(self) -> None:
|
|
490
|
+
source = self.input_source.currentData() or "local"
|
|
491
|
+
key = self.dataset_key.currentData() or self.dataset_key.currentText()
|
|
492
|
+
is_left_right = key == "left_right_data_of"
|
|
493
|
+
is_zh = str(self._lang).lower().startswith("zh")
|
|
494
|
+
show_dataset = source == "dataset"
|
|
495
|
+
if self.label_session is not None:
|
|
496
|
+
self.label_session.setVisible(is_left_right and show_dataset)
|
|
497
|
+
self.dataset_session.setVisible(is_left_right and show_dataset)
|
|
498
|
+
if self.label_filename is not None:
|
|
499
|
+
self.label_filename.setVisible(is_left_right and show_dataset)
|
|
500
|
+
self.dataset_filename.setVisible(is_left_right and show_dataset)
|
|
501
|
+
if self.label_dataset is not None:
|
|
502
|
+
self.label_dataset.setVisible(show_dataset)
|
|
503
|
+
self.dataset_key.setVisible(show_dataset)
|
|
504
|
+
if self.label_url is not None:
|
|
505
|
+
self.label_url.setVisible(source == "url")
|
|
506
|
+
self.dataset_url.setVisible(source == "url")
|
|
507
|
+
|
|
508
|
+
hint = ""
|
|
509
|
+
if source == "url":
|
|
510
|
+
hint = (
|
|
511
|
+
"加载包含 spike/x/y/t 的 .npz 链接。"
|
|
512
|
+
if is_zh
|
|
513
|
+
else "Load a .npz URL that contains spike/x/y/t."
|
|
514
|
+
)
|
|
515
|
+
elif source == "dataset":
|
|
516
|
+
try:
|
|
517
|
+
from canns.data import datasets as _datasets
|
|
518
|
+
|
|
519
|
+
info = _datasets.DATASETS.get(str(key))
|
|
520
|
+
if info:
|
|
521
|
+
size = info.get("size_mb", "?")
|
|
522
|
+
desc = info.get("description", "")
|
|
523
|
+
hint = f"{desc} (size ~{size} MB)" if not is_zh else f"{desc} (约 {size} MB)"
|
|
524
|
+
except Exception:
|
|
525
|
+
hint = ""
|
|
526
|
+
if is_left_right:
|
|
527
|
+
hint = ((hint + "\n") if hint else "") + (
|
|
528
|
+
"左/右数据集需要 session id 和文件名。"
|
|
529
|
+
if is_zh
|
|
530
|
+
else "Left-right dataset requires session id + filename."
|
|
531
|
+
)
|
|
532
|
+
self.dataset_hint.setText(hint)
|
|
533
|
+
|
|
389
534
|
def _toggle_embed_params(self) -> None:
|
|
390
535
|
method = self.preprocess_method.currentData() or "none"
|
|
391
536
|
self.embed_params.setVisible(method == "embed_spike_trains")
|
|
@@ -420,6 +565,96 @@ class PreprocessPage(QWidget):
|
|
|
420
565
|
}
|
|
421
566
|
return params
|
|
422
567
|
|
|
568
|
+
def _slugify(self, text: str) -> str:
|
|
569
|
+
out = []
|
|
570
|
+
for ch in text:
|
|
571
|
+
if ch.isalnum() or ch in ("-", "_"):
|
|
572
|
+
out.append(ch)
|
|
573
|
+
else:
|
|
574
|
+
out.append("_")
|
|
575
|
+
return "".join(out).strip("_") or "dataset"
|
|
576
|
+
|
|
577
|
+
def _normalize_npz_payload(self, data: dict) -> dict:
|
|
578
|
+
payload: dict = {}
|
|
579
|
+
for key, value in data.items():
|
|
580
|
+
if isinstance(value, dict):
|
|
581
|
+
payload[key] = np.array(value, dtype=object)
|
|
582
|
+
else:
|
|
583
|
+
payload[key] = value
|
|
584
|
+
return payload
|
|
585
|
+
|
|
586
|
+
def _prepare_dataset_asa(self) -> str | None:
|
|
587
|
+
source = self.input_source.currentData() or "local"
|
|
588
|
+
if source == "local":
|
|
589
|
+
return self.asa_zone.path()
|
|
590
|
+
|
|
591
|
+
data = None
|
|
592
|
+
label = ""
|
|
593
|
+
if source == "url":
|
|
594
|
+
url = self.dataset_url.text().strip()
|
|
595
|
+
if not url:
|
|
596
|
+
self.log_box.log("Please provide a dataset URL.")
|
|
597
|
+
return None
|
|
598
|
+
label = self._slugify(Path(url).stem or "dataset_url")
|
|
599
|
+
try:
|
|
600
|
+
from canns.data import datasets as _datasets
|
|
601
|
+
|
|
602
|
+
data = _datasets.load(url, file_type="numpy")
|
|
603
|
+
except Exception as exc:
|
|
604
|
+
self.log_box.log(f"Failed to load URL dataset: {exc}")
|
|
605
|
+
return None
|
|
606
|
+
elif source == "dataset":
|
|
607
|
+
key = self.dataset_key.currentData() or self.dataset_key.currentText()
|
|
608
|
+
label = self._slugify(str(key))
|
|
609
|
+
try:
|
|
610
|
+
from canns.data import datasets as _datasets
|
|
611
|
+
from canns.data import loaders as _loaders
|
|
612
|
+
|
|
613
|
+
if key == "roi_data":
|
|
614
|
+
data = _loaders.load_roi_data()
|
|
615
|
+
elif key == "left_right_data_of":
|
|
616
|
+
session_id = self.dataset_session.text().strip()
|
|
617
|
+
filename = self.dataset_filename.text().strip()
|
|
618
|
+
if not session_id or not filename:
|
|
619
|
+
self.log_box.log("Left-Right dataset requires session id + filename.")
|
|
620
|
+
return None
|
|
621
|
+
data = _loaders.load_left_right_npz(session_id=session_id, filename=filename)
|
|
622
|
+
label = self._slugify(f"{session_id}_{filename}")
|
|
623
|
+
elif str(key).startswith("grid_"):
|
|
624
|
+
data = _loaders.load_grid_data(dataset_key=str(key))
|
|
625
|
+
else:
|
|
626
|
+
path = _datasets.download_dataset(str(key))
|
|
627
|
+
if path is not None and path.exists():
|
|
628
|
+
data = dict(np.load(path, allow_pickle=True))
|
|
629
|
+
except Exception as exc:
|
|
630
|
+
self.log_box.log(f"Failed to load dataset '{key}': {exc}")
|
|
631
|
+
return None
|
|
632
|
+
|
|
633
|
+
if data is None:
|
|
634
|
+
self.log_box.log("Dataset load failed or returned empty data.")
|
|
635
|
+
return None
|
|
636
|
+
|
|
637
|
+
if not isinstance(data, dict):
|
|
638
|
+
self.log_box.log("Dataset is not an ASA .npz dict (missing spike/x/y/t).")
|
|
639
|
+
return None
|
|
640
|
+
|
|
641
|
+
payload = self._normalize_npz_payload(data)
|
|
642
|
+
if "spike" not in payload or "t" not in payload:
|
|
643
|
+
self.log_box.log("Dataset does not contain required keys: spike, t.")
|
|
644
|
+
return None
|
|
645
|
+
|
|
646
|
+
out_dir = Path.cwd() / "Results" / "asa_gui_datasets"
|
|
647
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
648
|
+
out_path = out_dir / f"{label}.npz"
|
|
649
|
+
try:
|
|
650
|
+
np.savez_compressed(out_path, **payload)
|
|
651
|
+
except Exception as exc:
|
|
652
|
+
self.log_box.log(f"Failed to save dataset as npz: {exc}")
|
|
653
|
+
return None
|
|
654
|
+
|
|
655
|
+
self.asa_zone.set_path(str(out_path))
|
|
656
|
+
return str(out_path)
|
|
657
|
+
|
|
423
658
|
def _run_preprocess(self) -> None:
|
|
424
659
|
if self._workers.is_running():
|
|
425
660
|
self.log_box.log("A task is already running.")
|
|
@@ -433,6 +668,9 @@ class PreprocessPage(QWidget):
|
|
|
433
668
|
neuron_file = self.neuron_zone.path() if input_mode != "asa" else None
|
|
434
669
|
traj_file = self.traj_zone.path() if input_mode != "asa" else None
|
|
435
670
|
|
|
671
|
+
if input_mode == "asa":
|
|
672
|
+
asa_file = self._prepare_dataset_asa()
|
|
673
|
+
|
|
436
674
|
if not self._validate_inputs(asa_file):
|
|
437
675
|
return
|
|
438
676
|
|
|
@@ -509,13 +747,17 @@ class PreprocessPage(QWidget):
|
|
|
509
747
|
return True
|
|
510
748
|
|
|
511
749
|
def _update_run_enabled(self) -> None:
|
|
750
|
+
source = self.input_source.currentData() or "local"
|
|
512
751
|
asa_file = self.asa_zone.path()
|
|
513
752
|
valid = False
|
|
514
|
-
if asa_file:
|
|
753
|
+
if source == "local" and asa_file:
|
|
515
754
|
path = Path(asa_file)
|
|
516
755
|
valid = path.exists() and path.suffix.lower() == ".npz"
|
|
517
756
|
self.run_btn.setEnabled(True)
|
|
518
|
-
if
|
|
519
|
-
|
|
757
|
+
if source == "local":
|
|
758
|
+
if valid:
|
|
759
|
+
self.run_btn.setToolTip("")
|
|
760
|
+
else:
|
|
761
|
+
self.run_btn.setToolTip("Select a valid ASA .npz file to run preprocessing.")
|
|
520
762
|
else:
|
|
521
|
-
self.run_btn.setToolTip("
|
|
763
|
+
self.run_btn.setToolTip("Dataset/URL will be loaded on Run.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: canns
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: A Python Library for Continuous Attractor Neural Networks
|
|
5
5
|
Project-URL: Repository, https://github.com/routhleck/canns
|
|
6
6
|
Author-email: Sichao He <sichaohe@outlook.com>
|
|
@@ -44,6 +44,7 @@ Requires-Dist: imageio; extra == 'gui'
|
|
|
44
44
|
Requires-Dist: pillow; extra == 'gui'
|
|
45
45
|
Requires-Dist: pyside6>=6.6.0; extra == 'gui'
|
|
46
46
|
Requires-Dist: qtawesome; extra == 'gui'
|
|
47
|
+
Requires-Dist: requests>=2.31.0; extra == 'gui'
|
|
47
48
|
Provides-Extra: tpu
|
|
48
49
|
Requires-Dist: brainpy[tpu]; (platform_system == 'Linux') and extra == 'tpu'
|
|
49
50
|
Description-Content-Type: text/markdown
|
|
@@ -3,19 +3,26 @@ canns/_version.py,sha256=zIvJPOGBFvo4VV6f586rlO_bvhuFp1fsxjf6xhsqkJY,1547
|
|
|
3
3
|
canns/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
canns/analyzer/__init__.py,sha256=EQ02fYHkpMADp-ojpVCVtapuSPkl6j5WVfdPy0mOTs4,506
|
|
5
5
|
canns/analyzer/data/__init__.py,sha256=RfS8vwApLkNF05Y_lfPaJpN_bRv-mOA_uFziaduDHgI,354
|
|
6
|
-
canns/analyzer/data/asa/__init__.py,sha256=
|
|
7
|
-
canns/analyzer/data/asa/
|
|
6
|
+
canns/analyzer/data/asa/__init__.py,sha256=nXaRd49ePAnrjJaUO-FNkN_RlldEkC55e9jszEhmYKM,3897
|
|
7
|
+
canns/analyzer/data/asa/coho.py,sha256=rYKb0ae2ZK7PX_XkDd7JOVNmPRStG6ZLCKvUsseoK1g,2884
|
|
8
|
+
canns/analyzer/data/asa/cohomap.py,sha256=EmlG13f948de1O7Sm9e0YACtjbp9lEoFWeG3-hWRu6M,13437
|
|
9
|
+
canns/analyzer/data/asa/cohomap_scatter.py,sha256=qu5F9UBCG-JuRrQL0Ag0ACAM61bzAGXEYpPgZ-Oqciw,231
|
|
10
|
+
canns/analyzer/data/asa/cohomap_vectors.py,sha256=krzLr-MSw4Az8VD0AZruXHkv6G9i6VOE6AgavDJCGIw,9113
|
|
11
|
+
canns/analyzer/data/asa/cohospace.py,sha256=dQ_HDNW6xGy6RRBUD8zK3FnQksjiupd84ORIwy6NKCE,7668
|
|
12
|
+
canns/analyzer/data/asa/cohospace_phase_centers.py,sha256=JqgDH_SJZOln5wFhnNJ_qnPTlsTBFWb3M5VZX5b0Wrk,4113
|
|
13
|
+
canns/analyzer/data/asa/cohospace_scatter.py,sha256=z13lLFdYkODmjKeOYildM5TgvT2QxmFSh7q8BYS5WjA,37163
|
|
8
14
|
canns/analyzer/data/asa/config.py,sha256=qm0k0nt0xuDUK5t63MG7ii7fgs2XbxyLxKOaOKJuB_s,6398
|
|
9
15
|
canns/analyzer/data/asa/decode.py,sha256=NG8vVx2cPG7uSJDovnC2vzk0dsqU8oR4jaNPxxrvCc0,16501
|
|
10
|
-
canns/analyzer/data/asa/embedding.py,sha256=
|
|
16
|
+
canns/analyzer/data/asa/embedding.py,sha256=CupBvkqZJ7zDMQWH-aIfqrOPTdUfv6wfTtZrI4tj0f0,9623
|
|
11
17
|
canns/analyzer/data/asa/filters.py,sha256=D-1mDVn4hBEAphKUgx1gQEUfgbghKcNQhZmr4xEExQA,7146
|
|
12
18
|
canns/analyzer/data/asa/fly_roi.py,sha256=_scBOd-4t9yv_1tHk7wbXJwPieU-L-QtFJY6fhHpxDI,38031
|
|
13
19
|
canns/analyzer/data/asa/fr.py,sha256=jt99H50e1RRAQgMIdkfK0rBbembZJEr9SMrxK-ZI_LA,13449
|
|
14
20
|
canns/analyzer/data/asa/path.py,sha256=dL6hsqBoPFfC4ZrHDVFDWprbRfJAAYpiq4tIkZ6NvHY,15540
|
|
15
|
-
canns/analyzer/data/asa/plotting.py,sha256=
|
|
21
|
+
canns/analyzer/data/asa/plotting.py,sha256=lpQfN55Sy8B5P1YSQhch_wc0e6SIEVCw9Wch7wHw04o,42798
|
|
16
22
|
canns/analyzer/data/asa/tda.py,sha256=7IdxhBNEE99qenG6Zi4B5tv_L9K6gAW6HHxYGiErx4c,30574
|
|
17
|
-
canns/analyzer/data/cell_classification/__init__.py,sha256=
|
|
18
|
-
canns/analyzer/data/cell_classification/core/__init__.py,sha256=
|
|
23
|
+
canns/analyzer/data/cell_classification/__init__.py,sha256=Ri0VJYn2OI3ygC4m-Xc9rjFvgPLaEykc-D94VxmUclQ,2447
|
|
24
|
+
canns/analyzer/data/cell_classification/core/__init__.py,sha256=J9uqjx2wTK-uh3OWFqP8BkY_ySz3rU_VWRNQ_1t3EbM,865
|
|
25
|
+
canns/analyzer/data/cell_classification/core/btn.py,sha256=rgZdEoMgqgOPah5KHEQAx7pNWDsWBzZ2pNQ5BstTYFM,8546
|
|
19
26
|
canns/analyzer/data/cell_classification/core/grid_cells.py,sha256=fRFixjvPVJy0QF9MygGqpIk1lnTToMZvvbGubM5woRk,21547
|
|
20
27
|
canns/analyzer/data/cell_classification/core/grid_modules_leiden.py,sha256=xWrbL51BeU9pIaCzak54upFBeSUtnx_V_naILjzzExk,9032
|
|
21
28
|
canns/analyzer/data/cell_classification/core/head_direction.py,sha256=CQKyon9pb3K5SBkesuqkBTU-QXx_-g0FBa0bblWDPOw,12060
|
|
@@ -27,7 +34,8 @@ canns/analyzer/data/cell_classification/utils/circular_stats.py,sha256=fQ1PNBiF_
|
|
|
27
34
|
canns/analyzer/data/cell_classification/utils/correlation.py,sha256=57Ckn8OQGLipT7qZIGl6wgooQ_8gwp01g9lVc8I3Cs0,10354
|
|
28
35
|
canns/analyzer/data/cell_classification/utils/geometry.py,sha256=jOLh3GeO-riR5a7r7Q7uON3HU_bYOZZJLbokU5bjCOQ,12683
|
|
29
36
|
canns/analyzer/data/cell_classification/utils/image_processing.py,sha256=o9bLT4ycJ_IF7SKBe2RqSWIQwNcpi9v4AI-N5vpm_jM,12805
|
|
30
|
-
canns/analyzer/data/cell_classification/visualization/__init__.py,sha256=
|
|
37
|
+
canns/analyzer/data/cell_classification/visualization/__init__.py,sha256=fmEHZBcurW6y6FwySLoq65b6CH2kNUB02NCVw2ou6Nc,590
|
|
38
|
+
canns/analyzer/data/cell_classification/visualization/btn_plots.py,sha256=nl29Ihe-gayCu_poJIWLN9oT6Srg1yjC-okPZ0IeRjo,7702
|
|
31
39
|
canns/analyzer/data/cell_classification/visualization/grid_plots.py,sha256=NFtyYOe2Szt0EOIwQmZradwEvvRjjm7mm6VnnGThDQ0,7914
|
|
32
40
|
canns/analyzer/data/cell_classification/visualization/hd_plots.py,sha256=nzw1jck3VHvAFsJAGelhrJf1q27A5PI0r3NKVgeea8U,5670
|
|
33
41
|
canns/analyzer/metrics/__init__.py,sha256=DTsrv1HW133_RgvhWzz7Gx-bP2hOZbPO2unCPPyf9gs,178
|
|
@@ -41,16 +49,16 @@ canns/analyzer/slow_points/checkpoint.py,sha256=s4_-5HZJvmnyFqpK1O9WWYkhAhZj1i5j
|
|
|
41
49
|
canns/analyzer/slow_points/finder.py,sha256=y-YKg-LI7lRM4JMghfcb5NGSYhIM2VPRA37YSCkVK_4,25437
|
|
42
50
|
canns/analyzer/slow_points/fixed_points.py,sha256=Qp-iezwydWWUTchb2hGXJv0QKJqIm9gSG6hh0H9Eb6E,10099
|
|
43
51
|
canns/analyzer/slow_points/visualization.py,sha256=sRmmxs900OSB680MTp0PNIGLpS5i5AmJ58ek20vmrSE,10610
|
|
44
|
-
canns/analyzer/visualization/__init__.py,sha256=
|
|
52
|
+
canns/analyzer/visualization/__init__.py,sha256=_4a8mrVOr8TR63LZbXym-djYbW-6vxxI78dxiHpSsho,2211
|
|
45
53
|
canns/analyzer/visualization/energy_plots.py,sha256=u0TOLzd7AWEfs-tRYZg1UBwsGYGPF_eWsMip1ZG9jPA,35671
|
|
46
54
|
canns/analyzer/visualization/spatial_plots.py,sha256=30m02xhYkZfEETCtvBSwLix9SEOPcLZTg0AGGFvPc2w,34605
|
|
47
55
|
canns/analyzer/visualization/spike_plots.py,sha256=wOm4gh_3obJy6gwo31maoaiZ7O8rsoYeFdhseoVmX78,12280
|
|
48
|
-
canns/analyzer/visualization/theta_sweep_plots.py,sha256=
|
|
56
|
+
canns/analyzer/visualization/theta_sweep_plots.py,sha256=BPW0VRR-rSJcJkMkY-Z1NpMS3iPIgLe3w0ZLBnHfeog,67723
|
|
49
57
|
canns/analyzer/visualization/tuning_plots.py,sha256=9JOeC4dlulVzpHQWDVy3dlJnxcBZiOPeapPdVFR-7Zk,5178
|
|
50
58
|
canns/analyzer/visualization/core/__init__.py,sha256=Vngm2A05cTu9ZVEYepTF7lVpuwQvMRjXs9XPLfZzedI,1928
|
|
51
59
|
canns/analyzer/visualization/core/animation.py,sha256=qfBYMd81_GwWEw4MHOu3GrVXJtHS9W1xxtmOx-J5ZyM,7664
|
|
52
60
|
canns/analyzer/visualization/core/backend.py,sha256=Nbk-ARL_xeWlb3nl5SUPrFQNns2wq5BeHU3Q_tAbd_c,9539
|
|
53
|
-
canns/analyzer/visualization/core/config.py,sha256=
|
|
61
|
+
canns/analyzer/visualization/core/config.py,sha256=2-YIFa-eqtUrNPJERTpPO-PPX0PdOaAioi95VT9WUbQ,26268
|
|
54
62
|
canns/analyzer/visualization/core/jupyter_utils.py,sha256=JD56VeeWb7w9t5DJ8TpgnxRWkUK46ArbbPSTlFdIM10,6034
|
|
55
63
|
canns/analyzer/visualization/core/rendering.py,sha256=YCbiXu8MOAqE9FVb_id5JKr5g9O64sCh-dOs0EK4gnU,18291
|
|
56
64
|
canns/analyzer/visualization/core/writers.py,sha256=HLsP953hgsv140ZX2XPzHfCUTqenjmjbLNrbknKam_s,15607
|
|
@@ -76,12 +84,12 @@ canns/pipeline/launcher.py,sha256=GASiWSfezljY56swjfLUR_QZCUU5Acm4v3mh9kNYayE,19
|
|
|
76
84
|
canns/pipeline/asa/__init__.py,sha256=JR4T0onfmkKMOrUq-k0San1RTSb1om6cd27tWovBp0c,466
|
|
77
85
|
canns/pipeline/asa/__main__.py,sha256=_KgAeuGQ2-SXmuZhvZCkRx9luFf7VgKUCuszNlUswyA,197
|
|
78
86
|
canns/pipeline/asa/app.py,sha256=L5al6PrGoEzRNosZlHbn-VaTxXCoVyfKFn0f1e-0FUI,49906
|
|
79
|
-
canns/pipeline/asa/runner.py,sha256=
|
|
87
|
+
canns/pipeline/asa/runner.py,sha256=FFz1Sfk5ysyHgoXAl-TK100nA27plLcO7Z7xUZ0COd4,45398
|
|
80
88
|
canns/pipeline/asa/screens.py,sha256=DbqidxmoKe4KzSLuxuriVv1PIVFn5Z-PfScVfjrIiEA,5954
|
|
81
89
|
canns/pipeline/asa/state.py,sha256=XukidfcFIOmm9ttT226FOTYR5hv2VAY8_DZt7V1Ml2g,6955
|
|
82
90
|
canns/pipeline/asa/styles.tcss,sha256=eaXI3rQeWdBYmWdLJMMiSO6acHtreLRVKKoIHb2-dBk,3349
|
|
83
91
|
canns/pipeline/asa/widgets.py,sha256=3vPGGQWP9V5FwuwqykCVp7dzAHdpcFkDqib0DtIw-lQ,8087
|
|
84
|
-
canns/pipeline/asa_gui/__init__.py,sha256=
|
|
92
|
+
canns/pipeline/asa_gui/__init__.py,sha256=FthSerbWbpOjwNp9z4c20mu1fcIvRnBiYzl5ALVh_NE,2280
|
|
85
93
|
canns/pipeline/asa_gui/__main__.py,sha256=2UOQtIE5oXkcq9HcuY13M3Jk6-uaDu8A0VJfvr203ck,134
|
|
86
94
|
canns/pipeline/asa_gui/app.py,sha256=Wd-tVGNPE1mQ0S9bET-cyjfj5UWsTIFFHOQRu0lngBs,833
|
|
87
95
|
canns/pipeline/asa_gui/main_window.py,sha256=kQp8DTmp7SuYVCglh5lVja7DyQ7hAOxPgCEUmjKHgbk,7019
|
|
@@ -94,14 +102,14 @@ canns/pipeline/asa_gui/analysis_modes/decode_mode.py,sha256=uEe3lfWAA0pqmCXzNpaA
|
|
|
94
102
|
canns/pipeline/asa_gui/analysis_modes/fr_mode.py,sha256=xzx1RhGVDbx6huEtEHGfUqWgRN_C6Sf-Ycj9BzIgTRY,3961
|
|
95
103
|
canns/pipeline/asa_gui/analysis_modes/frm_mode.py,sha256=8rgh_P7dxYJfx2TxrhD00Ja6tK0q6NboqwZ7n0Sw_2U,3992
|
|
96
104
|
canns/pipeline/asa_gui/analysis_modes/gridscore_mode.py,sha256=XC-O2lMx3NPxUkSoZo_69g7B_yFAYUnKIPKLj9-gKM4,5712
|
|
97
|
-
canns/pipeline/asa_gui/analysis_modes/pathcompare_mode.py,sha256=
|
|
105
|
+
canns/pipeline/asa_gui/analysis_modes/pathcompare_mode.py,sha256=d3R19eHz44z2YP3UFUNcQFDJGg0qp3Giv_7uWGCMzAo,10838
|
|
98
106
|
canns/pipeline/asa_gui/analysis_modes/tda_mode.py,sha256=xnsWv_zfstzYPf_nLbQkCNHxxhYRznz4m-73ClaBQKs,6094
|
|
99
107
|
canns/pipeline/asa_gui/controllers/__init__.py,sha256=RuQz960T4kEuQsBI_cjS0cQgFyqAdblLXy_dDoLPbTE,198
|
|
100
108
|
canns/pipeline/asa_gui/controllers/analysis_controller.py,sha256=8cKs-RYHh_NflP7xeS0u0_y9WsZ268H1Wyp-wHZC97I,1769
|
|
101
109
|
canns/pipeline/asa_gui/controllers/preprocess_controller.py,sha256=uNZifNGadYPxAVyWnfonOs5pwCgxwB1nrBGqvv8Y3hU,2825
|
|
102
110
|
canns/pipeline/asa_gui/core/__init__.py,sha256=vfJVs5T999vh04Fi98kRLjD8AkbqpIGxmRiUhaxCNYY,371
|
|
103
111
|
canns/pipeline/asa_gui/core/cache.py,sha256=qAg9Su_T1xIR5j8DK9KzwSdCGs0lKtMaZKr0Lhcj0KU,327
|
|
104
|
-
canns/pipeline/asa_gui/core/runner.py,sha256=
|
|
112
|
+
canns/pipeline/asa_gui/core/runner.py,sha256=PgD4WHxKDo9Nos-djo98DRcYKNB0sdgrc41WjtxG6TE,74693
|
|
105
113
|
canns/pipeline/asa_gui/core/state.py,sha256=hjv8NrgROlACgjm5VZtQL58_podJFWS2sLHi5YiVLJY,10148
|
|
106
114
|
canns/pipeline/asa_gui/core/worker.py,sha256=ig6fwcMLNR6N3oSX3LW-bJdXm3Hol29iAVX9pU6KWSc,7778
|
|
107
115
|
canns/pipeline/asa_gui/models/__init__.py,sha256=Pr5wfeu_iA8bh2ob9tfWQcWmzWydYjMwups29R6c8-U,217
|
|
@@ -122,7 +130,7 @@ canns/pipeline/asa_gui/views/__init__.py,sha256=ThoLlMw7bKxA7lkv_AvIR1mbpaoM0vkI
|
|
|
122
130
|
canns/pipeline/asa_gui/views/help_content.py,sha256=kL7MSwc9v3gHLz86Apiy64xbwymt9r7sPEjz5ka6EB0,8452
|
|
123
131
|
canns/pipeline/asa_gui/views/pages/__init__.py,sha256=xB7VTY_hKfoCNMGeWZbV3gHG9ErrzmwqW30UlUkbqgE,161
|
|
124
132
|
canns/pipeline/asa_gui/views/pages/analysis_page.py,sha256=X6PGW_cgvAiNFqUpsS2TuVWl258Q6Q90C9NEQT1TetQ,22807
|
|
125
|
-
canns/pipeline/asa_gui/views/pages/preprocess_page.py,sha256=
|
|
133
|
+
canns/pipeline/asa_gui/views/pages/preprocess_page.py,sha256=QNKLCL5y_nmmdYUh6GiDI12-sBXYU_z3OpU9ovZ-DXc,31303
|
|
126
134
|
canns/pipeline/asa_gui/views/panels/__init__.py,sha256=Spqmc0Sjh38cgr42gszmiogZQFFOLN1yL7ekSpVJCrE,36
|
|
127
135
|
canns/pipeline/asa_gui/views/widgets/__init__.py,sha256=xaTYXw99OL8ye1cpfoKgSwqC7c2B6lrLLsYHRB16m64,481
|
|
128
136
|
canns/pipeline/asa_gui/views/widgets/artifacts_tab.py,sha256=U_fuOCfSmkDhx3G97aod-8UPSIFVz_MrsU4b_ik_5qE,1431
|
|
@@ -158,8 +166,8 @@ canns/trainer/utils.py,sha256=ZdoLiRqFLfKXsWi0KX3wGUp0OqFikwiou8dPf3xvFhE,2847
|
|
|
158
166
|
canns/typing/__init__.py,sha256=mXySdfmD8fA56WqZTb1Nj-ZovcejwLzNjuk6PRfTwmA,156
|
|
159
167
|
canns/utils/__init__.py,sha256=OMyZ5jqZAIUS2Jr0qcnvvrx6YM-BZ1EJy5uZYeA3HC0,366
|
|
160
168
|
canns/utils/benchmark.py,sha256=oJ7nvbvnQMh4_MZh7z160NPLp-197X0rEnmnLHYlev4,1361
|
|
161
|
-
canns-0.
|
|
162
|
-
canns-0.
|
|
163
|
-
canns-0.
|
|
164
|
-
canns-0.
|
|
165
|
-
canns-0.
|
|
169
|
+
canns-0.15.0.dist-info/METADATA,sha256=18mW4kldZzRDEw-pm3KnNp_mIQWjoGbj_sFw43GnaSE,9799
|
|
170
|
+
canns-0.15.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
171
|
+
canns-0.15.0.dist-info/entry_points.txt,sha256=57YF2HZp_BG3GeGB8L0m3wR1sSfNyMXF1q4CKEjce6U,164
|
|
172
|
+
canns-0.15.0.dist-info/licenses/LICENSE,sha256=u6NJ1N-QSnf5yTwSk5UvFAdU2yKD0jxG0Xa91n1cPO4,11306
|
|
173
|
+
canns-0.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|