canns 0.14.2__py3-none-any.whl → 0.14.3__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.
@@ -10,6 +10,7 @@ from PySide6.QtWidgets import (
10
10
  QHBoxLayout,
11
11
  QLabel,
12
12
  QLineEdit,
13
+ QPushButton,
13
14
  QSpinBox,
14
15
  QWidget,
15
16
  )
@@ -49,7 +50,7 @@ class PathCompareMode(AbstractAnalysisMode):
49
50
  self.dim2.setValue(2)
50
51
 
51
52
  self.use_box = QCheckBox("Use coordsbox / times_box")
52
- self.use_box.setChecked(False)
53
+ self.use_box.setChecked(True)
53
54
 
54
55
  self.interp_full = QCheckBox("Interpolate to full trajectory")
55
56
  self.interp_full.setChecked(True)
@@ -57,8 +58,13 @@ class PathCompareMode(AbstractAnalysisMode):
57
58
 
58
59
  self.coords_key = QLineEdit()
59
60
  self.coords_key.setPlaceholderText("coords / coordsbox (optional)")
61
+ self.btn_coordsbox = QPushButton("coordsbox")
62
+ self.btn_coordsbox.clicked.connect(lambda: self.coords_key.setText("coordsbox"))
63
+
60
64
  self.times_key = QLineEdit()
61
65
  self.times_key.setPlaceholderText("times_box (optional)")
66
+ self.btn_times_box = QPushButton("times_box")
67
+ self.btn_times_box.clicked.connect(lambda: self.times_key.setText("times_box"))
62
68
 
63
69
  self.slice_mode = PopupComboBox()
64
70
  self.slice_mode.addItem("Time (tmin/tmax)", userData="time")
@@ -125,8 +131,20 @@ class PathCompareMode(AbstractAnalysisMode):
125
131
  form.addRow(self._dims2d_label, dims_2d)
126
132
  form.addRow(self.use_box)
127
133
  form.addRow(self.interp_full)
128
- form.addRow("coords key", self.coords_key)
129
- form.addRow("times key", self.times_key)
134
+ coords_row = QWidget()
135
+ coords_layout = QHBoxLayout(coords_row)
136
+ coords_layout.setContentsMargins(0, 0, 0, 0)
137
+ coords_layout.addWidget(self.coords_key, 1)
138
+ coords_layout.addWidget(self.btn_coordsbox)
139
+
140
+ times_row = QWidget()
141
+ times_layout = QHBoxLayout(times_row)
142
+ times_layout.setContentsMargins(0, 0, 0, 0)
143
+ times_layout.addWidget(self.times_key, 1)
144
+ times_layout.addWidget(self.btn_times_box)
145
+
146
+ form.addRow("coords key", coords_row)
147
+ form.addRow("times key", times_row)
130
148
  form.addRow("Slice mode", self.slice_mode)
131
149
  form.addRow("tmin (sec, -1=auto)", self.tmin)
132
150
  form.addRow("tmax (sec, -1=auto)", self.tmax)
@@ -150,6 +168,10 @@ class PathCompareMode(AbstractAnalysisMode):
150
168
  def _refresh_enabled() -> None:
151
169
  use_box = bool(self.use_box.isChecked())
152
170
  self.interp_full.setEnabled(use_box)
171
+ self.coords_key.setEnabled(use_box)
172
+ self.times_key.setEnabled(use_box)
173
+ self.btn_coordsbox.setEnabled(use_box)
174
+ self.btn_times_box.setEnabled(use_box)
153
175
 
154
176
  def _refresh_slice_mode() -> None:
155
177
  is_time = self.slice_mode.currentData() == "time"
@@ -210,6 +232,8 @@ class PathCompareMode(AbstractAnalysisMode):
210
232
  self.interp_full.setToolTip("插值回完整轨迹。")
211
233
  self.coords_key.setToolTip("可选:解码坐标键(默认 coords/coordsbox)。")
212
234
  self.times_key.setToolTip("可选:times_box 键名。")
235
+ self.btn_coordsbox.setToolTip("填入 coordsbox。")
236
+ self.btn_times_box.setToolTip("填入 times_box。")
213
237
  self.slice_mode.setToolTip("按时间或索引裁剪。")
214
238
  self.tmin.setToolTip("起始时间(秒),-1 自动。")
215
239
  self.tmax.setToolTip("结束时间(秒),-1 自动。")
@@ -230,6 +254,8 @@ class PathCompareMode(AbstractAnalysisMode):
230
254
  self.interp_full.setToolTip("Interpolate back to full trajectory.")
231
255
  self.coords_key.setToolTip("Optional decode coords key (default coords/coordsbox).")
232
256
  self.times_key.setToolTip("Optional times_box key.")
257
+ self.btn_coordsbox.setToolTip("Fill coordsbox.")
258
+ self.btn_times_box.setToolTip("Fill times_box.")
233
259
  self.slice_mode.setToolTip("Slice by time or index.")
234
260
  self.tmin.setToolTip("Start time (sec), -1 = auto.")
235
261
  self.tmax.setToolTip("End time (sec), -1 = auto.")
@@ -4,6 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  from pathlib import Path
6
6
 
7
+ import numpy as np
8
+
7
9
  from PySide6.QtCore import QSettings, Qt, Signal
8
10
  from PySide6.QtGui import QColor
9
11
  from PySide6.QtWidgets import (
@@ -15,6 +17,7 @@ from PySide6.QtWidgets import (
15
17
  QGroupBox,
16
18
  QHBoxLayout,
17
19
  QLabel,
20
+ QLineEdit,
18
21
  QProgressBar,
19
22
  QPushButton,
20
23
  QSpinBox,
@@ -86,6 +89,12 @@ class PreprocessPage(QWidget):
86
89
  self.preset.addItems(["grid", "hd", "none"])
87
90
  self.preset.setToolTip("Preset hints apply to analysis mode defaults.")
88
91
 
92
+ self.input_source = PopupComboBox()
93
+ self.input_source.addItem("Local file", userData="local")
94
+ self.input_source.addItem("CANNs dataset", userData="dataset")
95
+ self.input_source.addItem("URL", userData="url")
96
+ self.input_source.currentIndexChanged.connect(self._toggle_input_source)
97
+
89
98
  self.label_mode = QLabel("Mode")
90
99
  top_row.addWidget(self.label_mode)
91
100
  top_row.addWidget(self.input_mode)
@@ -93,6 +102,10 @@ class PreprocessPage(QWidget):
93
102
  self.label_preset = QLabel("Preset")
94
103
  top_row.addWidget(self.label_preset)
95
104
  top_row.addWidget(self.preset)
105
+ top_row.addSpacing(16)
106
+ self.label_source = QLabel("Source")
107
+ top_row.addWidget(self.label_source)
108
+ top_row.addWidget(self.input_source)
96
109
  top_row.addStretch(1)
97
110
  input_layout.addLayout(top_row)
98
111
 
@@ -126,6 +139,46 @@ class PreprocessPage(QWidget):
126
139
  input_layout.addLayout(neuron_row)
127
140
  input_layout.addLayout(traj_row)
128
141
 
142
+ self.dataset_group = QGroupBox("Dataset")
143
+ self.dataset_group.setObjectName("card")
144
+ dataset_form = QFormLayout(self.dataset_group)
145
+
146
+ self.dataset_key = PopupComboBox()
147
+ self.dataset_key.addItem("grid_1", userData="grid_1")
148
+ self.dataset_key.addItem("grid_2", userData="grid_2")
149
+ self.dataset_key.addItem("roi_data", userData="roi_data")
150
+ self.dataset_key.addItem("left_right_data_of", userData="left_right_data_of")
151
+ self.dataset_key.currentIndexChanged.connect(self._update_dataset_hint)
152
+
153
+ self.dataset_session = QLineEdit()
154
+ self.dataset_session.setPlaceholderText("e.g. 26034_3")
155
+
156
+ self.dataset_filename = QLineEdit()
157
+ self.dataset_filename.setPlaceholderText("e.g. 26034_3_ASA_full.npz")
158
+
159
+ self.dataset_url = QLineEdit()
160
+ self.dataset_url.setPlaceholderText("https://.../data.npz")
161
+
162
+ self.dataset_hint = QLabel("")
163
+ self.dataset_hint.setObjectName("muted")
164
+ self.dataset_hint.setWordWrap(True)
165
+
166
+ dataset_form.addRow("Dataset", self.dataset_key)
167
+ self.label_dataset = dataset_form.labelForField(self.dataset_key)
168
+ dataset_form.addRow("Session id", self.dataset_session)
169
+ self.label_session = dataset_form.labelForField(self.dataset_session)
170
+ dataset_form.addRow("Filename", self.dataset_filename)
171
+ self.label_filename = dataset_form.labelForField(self.dataset_filename)
172
+ url_row = QWidget()
173
+ url_layout = QHBoxLayout(url_row)
174
+ url_layout.setContentsMargins(0, 0, 0, 0)
175
+ url_layout.addWidget(self.dataset_url, 1)
176
+ dataset_form.addRow("URL", url_row)
177
+ self.label_url = dataset_form.labelForField(self.dataset_url)
178
+ dataset_form.addRow(self.dataset_hint)
179
+
180
+ input_layout.addWidget(self.dataset_group)
181
+
129
182
  top_layout.addWidget(input_group)
130
183
 
131
184
  # Preprocess group
@@ -244,6 +297,8 @@ class PreprocessPage(QWidget):
244
297
  self.asa_browse.clicked.connect(self._update_run_enabled)
245
298
 
246
299
  self._toggle_input_mode()
300
+ self._toggle_input_source()
301
+ self._update_dataset_hint()
247
302
  self._toggle_embed_params()
248
303
  self._update_run_enabled()
249
304
  self._apply_card_effects([input_group, preprocess_group, preclass_group])
@@ -270,6 +325,7 @@ class PreprocessPage(QWidget):
270
325
 
271
326
  self.label_mode.setText("模式" if is_zh else "Mode")
272
327
  self.label_preset.setText("预设" if is_zh else "Preset")
328
+ self.label_source.setText("来源" if is_zh else "Source")
273
329
  if self.label_method is not None:
274
330
  self.label_method.setText("方法" if is_zh else "Method")
275
331
  if self.label_preclass is not None:
@@ -317,6 +373,34 @@ class PreprocessPage(QWidget):
317
373
  self.stop_btn.setText("停止" if is_zh else "Stop")
318
374
  self.logs_label.setText("日志" if is_zh else "Logs")
319
375
 
376
+ self.dataset_group.setTitle("数据集" if is_zh else "Dataset")
377
+ if self.label_dataset is not None:
378
+ self.label_dataset.setText("数据集" if is_zh else "Dataset")
379
+ if self.label_session is not None:
380
+ self.label_session.setText("Session id" if not is_zh else "会话 id")
381
+ if self.label_filename is not None:
382
+ self.label_filename.setText("Filename" if not is_zh else "文件名")
383
+ if self.label_url is not None:
384
+ self.label_url.setText("URL")
385
+
386
+ self.input_source.setToolTip(
387
+ "选择本地文件、内置数据集或 URL"
388
+ if is_zh
389
+ else "Choose local file, built-in dataset, or URL."
390
+ )
391
+ self.dataset_key.setToolTip(
392
+ "选择内置数据集" if is_zh else "Select a built-in dataset."
393
+ )
394
+ self.dataset_session.setToolTip(
395
+ "Left-Right 数据集的会话 id。" if is_zh else "Session id for Left-Right dataset."
396
+ )
397
+ self.dataset_filename.setToolTip(
398
+ "Left-Right 数据集文件名。" if is_zh else "Filename within Left-Right dataset."
399
+ )
400
+ self.dataset_url.setToolTip(
401
+ "直接加载 .npz 链接。" if is_zh else "Load a .npz URL directly."
402
+ )
403
+
320
404
  self.input_mode.setToolTip(
321
405
  "仅支持 ASA .npz 输入" if is_zh else "Only ASA .npz input is supported in this GUI."
322
406
  )
@@ -346,6 +430,15 @@ class PreprocessPage(QWidget):
346
430
  else "Speed threshold (same unit as t/x/y)."
347
431
  )
348
432
 
433
+ self.dataset_session.setPlaceholderText("例如 26034_3" if is_zh else "e.g. 26034_3")
434
+ self.dataset_filename.setPlaceholderText(
435
+ "例如 26034_3_ASA_full.npz" if is_zh else "e.g. 26034_3_ASA_full.npz"
436
+ )
437
+ self.dataset_url.setPlaceholderText(
438
+ "https://.../data.npz" if not is_zh else "https://.../data.npz"
439
+ )
440
+ self._update_dataset_hint()
441
+
349
442
  def _show_help(self) -> None:
350
443
  lang = str(QSettings("canns", "asa_gui").value("lang", "en"))
351
444
  title = (
@@ -386,6 +479,63 @@ class PreprocessPage(QWidget):
386
479
  self.traj_zone.setVisible(not use_asa)
387
480
  self.traj_browse.setVisible(not use_asa)
388
481
 
482
+ def _toggle_input_source(self) -> None:
483
+ source = self.input_source.currentData() or "local"
484
+ use_local = source == "local"
485
+ self.asa_zone.setVisible(use_local)
486
+ self.asa_browse.setVisible(use_local)
487
+ self.asa_hint.setVisible(use_local)
488
+ self.dataset_group.setVisible(not use_local)
489
+ self._update_dataset_hint()
490
+ self._update_run_enabled()
491
+
492
+ def _update_dataset_hint(self) -> None:
493
+ source = self.input_source.currentData() or "local"
494
+ key = self.dataset_key.currentData() or self.dataset_key.currentText()
495
+ is_left_right = key == "left_right_data_of"
496
+ is_zh = str(self._lang).lower().startswith("zh")
497
+ show_dataset = source == "dataset"
498
+ if self.label_session is not None:
499
+ self.label_session.setVisible(is_left_right and show_dataset)
500
+ self.dataset_session.setVisible(is_left_right and show_dataset)
501
+ if self.label_filename is not None:
502
+ self.label_filename.setVisible(is_left_right and show_dataset)
503
+ self.dataset_filename.setVisible(is_left_right and show_dataset)
504
+ if self.label_dataset is not None:
505
+ self.label_dataset.setVisible(show_dataset)
506
+ self.dataset_key.setVisible(show_dataset)
507
+ if self.label_url is not None:
508
+ self.label_url.setVisible(source == "url")
509
+ self.dataset_url.setVisible(source == "url")
510
+
511
+ hint = ""
512
+ if source == "url":
513
+ hint = (
514
+ "加载包含 spike/x/y/t 的 .npz 链接。"
515
+ if is_zh
516
+ else "Load a .npz URL that contains spike/x/y/t."
517
+ )
518
+ elif source == "dataset":
519
+ try:
520
+ from canns.data import datasets as _datasets
521
+
522
+ info = _datasets.DATASETS.get(str(key))
523
+ if info:
524
+ size = info.get("size_mb", "?")
525
+ desc = info.get("description", "")
526
+ hint = f"{desc} (size ~{size} MB)" if not is_zh else f"{desc} (约 {size} MB)"
527
+ except Exception:
528
+ hint = ""
529
+ if is_left_right:
530
+ hint = (
531
+ (hint + "\n") if hint else ""
532
+ ) + (
533
+ "左/右数据集需要 session id 和文件名。"
534
+ if is_zh
535
+ else "Left-right dataset requires session id + filename."
536
+ )
537
+ self.dataset_hint.setText(hint)
538
+
389
539
  def _toggle_embed_params(self) -> None:
390
540
  method = self.preprocess_method.currentData() or "none"
391
541
  self.embed_params.setVisible(method == "embed_spike_trains")
@@ -420,6 +570,96 @@ class PreprocessPage(QWidget):
420
570
  }
421
571
  return params
422
572
 
573
+ def _slugify(self, text: str) -> str:
574
+ out = []
575
+ for ch in text:
576
+ if ch.isalnum() or ch in ("-", "_"):
577
+ out.append(ch)
578
+ else:
579
+ out.append("_")
580
+ return "".join(out).strip("_") or "dataset"
581
+
582
+ def _normalize_npz_payload(self, data: dict) -> dict:
583
+ payload: dict = {}
584
+ for key, value in data.items():
585
+ if isinstance(value, dict):
586
+ payload[key] = np.array(value, dtype=object)
587
+ else:
588
+ payload[key] = value
589
+ return payload
590
+
591
+ def _prepare_dataset_asa(self) -> str | None:
592
+ source = self.input_source.currentData() or "local"
593
+ if source == "local":
594
+ return self.asa_zone.path()
595
+
596
+ data = None
597
+ label = ""
598
+ if source == "url":
599
+ url = self.dataset_url.text().strip()
600
+ if not url:
601
+ self.log_box.log("Please provide a dataset URL.")
602
+ return None
603
+ label = self._slugify(Path(url).stem or "dataset_url")
604
+ try:
605
+ from canns.data import datasets as _datasets
606
+
607
+ data = _datasets.load(url, file_type="numpy")
608
+ except Exception as exc:
609
+ self.log_box.log(f"Failed to load URL dataset: {exc}")
610
+ return None
611
+ elif source == "dataset":
612
+ key = self.dataset_key.currentData() or self.dataset_key.currentText()
613
+ label = self._slugify(str(key))
614
+ try:
615
+ from canns.data import loaders as _loaders
616
+ from canns.data import datasets as _datasets
617
+
618
+ if key == "roi_data":
619
+ data = _loaders.load_roi_data()
620
+ elif key == "left_right_data_of":
621
+ session_id = self.dataset_session.text().strip()
622
+ filename = self.dataset_filename.text().strip()
623
+ if not session_id or not filename:
624
+ self.log_box.log("Left-Right dataset requires session id + filename.")
625
+ return None
626
+ data = _loaders.load_left_right_npz(session_id=session_id, filename=filename)
627
+ label = self._slugify(f"{session_id}_{filename}")
628
+ elif str(key).startswith("grid_"):
629
+ data = _loaders.load_grid_data(dataset_key=str(key))
630
+ else:
631
+ path = _datasets.download_dataset(str(key))
632
+ if path is not None and path.exists():
633
+ data = dict(np.load(path, allow_pickle=True))
634
+ except Exception as exc:
635
+ self.log_box.log(f"Failed to load dataset '{key}': {exc}")
636
+ return None
637
+
638
+ if data is None:
639
+ self.log_box.log("Dataset load failed or returned empty data.")
640
+ return None
641
+
642
+ if not isinstance(data, dict):
643
+ self.log_box.log("Dataset is not an ASA .npz dict (missing spike/x/y/t).")
644
+ return None
645
+
646
+ payload = self._normalize_npz_payload(data)
647
+ if "spike" not in payload or "t" not in payload:
648
+ self.log_box.log("Dataset does not contain required keys: spike, t.")
649
+ return None
650
+
651
+ out_dir = Path.cwd() / "Results" / "asa_gui_datasets"
652
+ out_dir.mkdir(parents=True, exist_ok=True)
653
+ out_path = out_dir / f"{label}.npz"
654
+ try:
655
+ np.savez_compressed(out_path, **payload)
656
+ except Exception as exc:
657
+ self.log_box.log(f"Failed to save dataset as npz: {exc}")
658
+ return None
659
+
660
+ self.asa_zone.set_path(str(out_path))
661
+ return str(out_path)
662
+
423
663
  def _run_preprocess(self) -> None:
424
664
  if self._workers.is_running():
425
665
  self.log_box.log("A task is already running.")
@@ -433,6 +673,9 @@ class PreprocessPage(QWidget):
433
673
  neuron_file = self.neuron_zone.path() if input_mode != "asa" else None
434
674
  traj_file = self.traj_zone.path() if input_mode != "asa" else None
435
675
 
676
+ if input_mode == "asa":
677
+ asa_file = self._prepare_dataset_asa()
678
+
436
679
  if not self._validate_inputs(asa_file):
437
680
  return
438
681
 
@@ -509,13 +752,17 @@ class PreprocessPage(QWidget):
509
752
  return True
510
753
 
511
754
  def _update_run_enabled(self) -> None:
755
+ source = self.input_source.currentData() or "local"
512
756
  asa_file = self.asa_zone.path()
513
757
  valid = False
514
- if asa_file:
758
+ if source == "local" and asa_file:
515
759
  path = Path(asa_file)
516
760
  valid = path.exists() and path.suffix.lower() == ".npz"
517
761
  self.run_btn.setEnabled(True)
518
- if valid:
519
- self.run_btn.setToolTip("")
762
+ if source == "local":
763
+ if valid:
764
+ self.run_btn.setToolTip("")
765
+ else:
766
+ self.run_btn.setToolTip("Select a valid ASA .npz file to run preprocessing.")
520
767
  else:
521
- self.run_btn.setToolTip("Select a valid ASA .npz file to run preprocessing.")
768
+ 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.14.2
3
+ Version: 0.14.3
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
@@ -94,7 +94,7 @@ canns/pipeline/asa_gui/analysis_modes/decode_mode.py,sha256=uEe3lfWAA0pqmCXzNpaA
94
94
  canns/pipeline/asa_gui/analysis_modes/fr_mode.py,sha256=xzx1RhGVDbx6huEtEHGfUqWgRN_C6Sf-Ycj9BzIgTRY,3961
95
95
  canns/pipeline/asa_gui/analysis_modes/frm_mode.py,sha256=8rgh_P7dxYJfx2TxrhD00Ja6tK0q6NboqwZ7n0Sw_2U,3992
96
96
  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=ODG6hxtRNj5CxeJgfr1JiX6AuokyBrPVBvTTJnd5SPw,9600
97
+ canns/pipeline/asa_gui/analysis_modes/pathcompare_mode.py,sha256=oRZPB8y7ORDFDPk99joRNQRj_e5qmR-GuJHrGnSynS4,10808
98
98
  canns/pipeline/asa_gui/analysis_modes/tda_mode.py,sha256=xnsWv_zfstzYPf_nLbQkCNHxxhYRznz4m-73ClaBQKs,6094
99
99
  canns/pipeline/asa_gui/controllers/__init__.py,sha256=RuQz960T4kEuQsBI_cjS0cQgFyqAdblLXy_dDoLPbTE,198
100
100
  canns/pipeline/asa_gui/controllers/analysis_controller.py,sha256=8cKs-RYHh_NflP7xeS0u0_y9WsZ268H1Wyp-wHZC97I,1769
@@ -122,7 +122,7 @@ canns/pipeline/asa_gui/views/__init__.py,sha256=ThoLlMw7bKxA7lkv_AvIR1mbpaoM0vkI
122
122
  canns/pipeline/asa_gui/views/help_content.py,sha256=kL7MSwc9v3gHLz86Apiy64xbwymt9r7sPEjz5ka6EB0,8452
123
123
  canns/pipeline/asa_gui/views/pages/__init__.py,sha256=xB7VTY_hKfoCNMGeWZbV3gHG9ErrzmwqW30UlUkbqgE,161
124
124
  canns/pipeline/asa_gui/views/pages/analysis_page.py,sha256=X6PGW_cgvAiNFqUpsS2TuVWl258Q6Q90C9NEQT1TetQ,22807
125
- canns/pipeline/asa_gui/views/pages/preprocess_page.py,sha256=ds8BHq4a9nsu3aAoojFR_jegO2RXNVYdgf3BnIxIG7M,20762
125
+ canns/pipeline/asa_gui/views/pages/preprocess_page.py,sha256=AHWidQqNKF0TBx8i2dDmPfxjT4Qy45_FjBYh-O1zB8E,31364
126
126
  canns/pipeline/asa_gui/views/panels/__init__.py,sha256=Spqmc0Sjh38cgr42gszmiogZQFFOLN1yL7ekSpVJCrE,36
127
127
  canns/pipeline/asa_gui/views/widgets/__init__.py,sha256=xaTYXw99OL8ye1cpfoKgSwqC7c2B6lrLLsYHRB16m64,481
128
128
  canns/pipeline/asa_gui/views/widgets/artifacts_tab.py,sha256=U_fuOCfSmkDhx3G97aod-8UPSIFVz_MrsU4b_ik_5qE,1431
@@ -158,8 +158,8 @@ canns/trainer/utils.py,sha256=ZdoLiRqFLfKXsWi0KX3wGUp0OqFikwiou8dPf3xvFhE,2847
158
158
  canns/typing/__init__.py,sha256=mXySdfmD8fA56WqZTb1Nj-ZovcejwLzNjuk6PRfTwmA,156
159
159
  canns/utils/__init__.py,sha256=OMyZ5jqZAIUS2Jr0qcnvvrx6YM-BZ1EJy5uZYeA3HC0,366
160
160
  canns/utils/benchmark.py,sha256=oJ7nvbvnQMh4_MZh7z160NPLp-197X0rEnmnLHYlev4,1361
161
- canns-0.14.2.dist-info/METADATA,sha256=QfJB-3QkIfsgIgwtY9jTYbzmvitph_jYNSGM1IDuvHg,9751
162
- canns-0.14.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
163
- canns-0.14.2.dist-info/entry_points.txt,sha256=57YF2HZp_BG3GeGB8L0m3wR1sSfNyMXF1q4CKEjce6U,164
164
- canns-0.14.2.dist-info/licenses/LICENSE,sha256=u6NJ1N-QSnf5yTwSk5UvFAdU2yKD0jxG0Xa91n1cPO4,11306
165
- canns-0.14.2.dist-info/RECORD,,
161
+ canns-0.14.3.dist-info/METADATA,sha256=UMyUaYFYtHoS60udBftAohcR0mIxJygdyUXyVdxfK18,9799
162
+ canns-0.14.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
163
+ canns-0.14.3.dist-info/entry_points.txt,sha256=57YF2HZp_BG3GeGB8L0m3wR1sSfNyMXF1q4CKEjce6U,164
164
+ canns-0.14.3.dist-info/licenses/LICENSE,sha256=u6NJ1N-QSnf5yTwSk5UvFAdU2yKD0jxG0Xa91n1cPO4,11306
165
+ canns-0.14.3.dist-info/RECORD,,
File without changes