mxbiflow 0.1.1__tar.gz → 0.1.2__tar.gz

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 (97) hide show
  1. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/PKG-INFO +1 -1
  2. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/pyproject.toml +1 -1
  3. mxbiflow-0.1.2/src/mxbiflow/__init__.py +12 -0
  4. mxbiflow-0.1.2/src/mxbiflow/default/__init__.py +3 -0
  5. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/default/idle/idle.py +0 -1
  6. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/models/session.py +1 -0
  7. mxbiflow-0.1.2/src/mxbiflow/mxbi.py +19 -0
  8. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/path.py +0 -4
  9. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/scene/__init__.py +1 -2
  10. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/scene/scene_manager.py +21 -16
  11. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/animal.py +4 -6
  12. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/experiment_groups.py +5 -6
  13. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/experiment_panel.py +7 -16
  14. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/mxbi_panel.py +5 -14
  15. mxbiflow-0.1.2/src/mxbiflow/ui/utils.py +25 -0
  16. mxbiflow-0.1.2/src/mxbiflow/utils/init_session.py +35 -0
  17. mxbiflow-0.1.1/src/mxbiflow/__init__.py +0 -3
  18. mxbiflow-0.1.1/src/mxbiflow/default/__init__.py +0 -4
  19. mxbiflow-0.1.1/src/mxbiflow/main.py +0 -106
  20. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/README.md +0 -0
  21. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/assets/__init__.py +0 -0
  22. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/assets/clicker.wav +0 -0
  23. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/config_store.py +0 -0
  24. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/data_logger.py +0 -0
  25. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/default/idle/assets/apple_v1.png +0 -0
  26. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/detector_bridge.py +0 -0
  27. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/game.py +0 -0
  28. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/infra/eventbus.py +0 -0
  29. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/models/animal.py +0 -0
  30. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/models/reward.py +0 -0
  31. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/mxbiflow.py +0 -0
  32. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/scene/scene_protocol.py +0 -0
  33. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/scheduler.py +0 -0
  34. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/models.py +0 -0
  35. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/detect_stage/config.json +0 -0
  36. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/detect_stage/detect_stage.py +0 -0
  37. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/detect_stage/detect_stage_models.py +0 -0
  38. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/discriminate_stage/config.json +0 -0
  39. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/discriminate_stage/discriminate_stage.py +0 -0
  40. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/discriminate_stage/discriminate_stage_models.py +0 -0
  41. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/size_reduction_stage/config.json +0 -0
  42. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/size_reduction_stage/size_reduction_models.py +0 -0
  43. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/stages/size_reduction_stage/size_reduction_stage.py +0 -0
  44. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/artifacts.py +0 -0
  45. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/detect/models.py +0 -0
  46. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/detect/scene.py +0 -0
  47. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/discriminate/discriminate_models.py +0 -0
  48. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/discriminate/discriminate_scene.py +0 -0
  49. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/touch/touch_models.py +0 -0
  50. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/touch/touch_scene.py +0 -0
  51. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/GNGSiD/tasks/utils/targets.py +0 -0
  52. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/bundle_dir.py +0 -0
  53. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/config.py +0 -0
  54. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/media.py +0 -0
  55. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/models.py +0 -0
  56. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/scene.py +0 -0
  57. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/stage.py +0 -0
  58. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/trial_io.py +0 -0
  59. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/cross_modal/trial_schema.py +0 -0
  60. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/error_task/error_scene.py +0 -0
  61. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/idle_task/assets/apple_v1.png +0 -0
  62. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/idle_task/idle_scene.py +0 -0
  63. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/README.md +0 -0
  64. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/stages/config.csv +0 -0
  65. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/stages/config.json +0 -0
  66. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/stages/initial_habituation_training_stage.py +0 -0
  67. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/stages/models.py +0 -0
  68. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/tasks/stay_to_reward/stay_to_reward.py +0 -0
  69. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/default/initial_habituation_training/tasks/stay_to_reward/stay_to_reward_models.py +0 -0
  70. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/task_protocol.py +0 -0
  71. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/task_table.py +0 -0
  72. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/assets/starter.py +0 -0
  73. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/models.py +0 -0
  74. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/stages/size_reduction_stage/config.json +0 -0
  75. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/stages/size_reduction_stage/size_reduction_models.py +0 -0
  76. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/stages/size_reduction_stage/size_reduction_stage.py +0 -0
  77. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/tasks/touch/touch_models.py +0 -0
  78. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tasks/two_alternative_choice/tasks/touch/touch_scene.py +0 -0
  79. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/timer/__init__.py +0 -0
  80. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/timer/frame_timer.py +0 -0
  81. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/timer/realtime_timer.py +0 -0
  82. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/tmp_email.py +0 -0
  83. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/baseconfig.py +0 -0
  84. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/card.py +0 -0
  85. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/__init__.py +0 -0
  86. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/detector/beambreak_detector_card.py +0 -0
  87. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/detector/fusion_detector.py +0 -0
  88. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/detector/mock_detector_card.py +0 -0
  89. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/detector/rfid_detector.py +0 -0
  90. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/device_card.py +0 -0
  91. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/rewarder/mock_rewarder_card.py +0 -0
  92. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/device_card/rewarder/rpi_gpio_rewarder.py +0 -0
  93. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/devices.py +0 -0
  94. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/dialog/__init__.py +0 -0
  95. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/ui/components/dialog/add_devices_dialog.py +0 -0
  96. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/utils/logger.py +0 -0
  97. {mxbiflow-0.1.1 → mxbiflow-0.1.2}/src/mxbiflow/utils/serial.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mxbiflow
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: mxbiflow is a toolkit based on pygame and pymxbi
5
5
  Author: HuYang
6
6
  Author-email: HuYang <huyangcommit@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mxbiflow"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "mxbiflow is a toolkit based on pygame and pymxbi"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "HuYang", email = "huyangcommit@gmail.com" }]
@@ -0,0 +1,12 @@
1
+ from .mxbi import build_mxbi
2
+ from .mxbiflow import MXBIFlow, get_mxbiflow
3
+ from .ui.utils import config_wizard
4
+ from .utils.init_session import init_session
5
+
6
+ __all__ = [
7
+ "MXBIFlow",
8
+ "get_mxbiflow",
9
+ "config_wizard",
10
+ "build_mxbi",
11
+ "init_session",
12
+ ]
@@ -0,0 +1,3 @@
1
+ from .idle.idle import IDLE
2
+
3
+ __all__ = ["IDLE"]
@@ -5,7 +5,6 @@ from random import choice
5
5
  from pygame import Event, Rect, Surface, image, transform
6
6
 
7
7
  from mxbiflow import get_mxbiflow
8
- from mxbiflow.scene.scene_protocol import SceneProtocol
9
8
 
10
9
  ASSETS_PATH = Path(__file__).parent / "assets"
11
10
 
@@ -143,3 +143,4 @@ class Options(BaseModel):
143
143
  mxbis: list[str] = Field(default_factory=list, frozen=True)
144
144
  experimenter: list[str] = Field(default_factory=list, frozen=True)
145
145
  animals: dict[str, str] = Field(default_factory=dict, frozen=True)
146
+ stages: list[str] = Field(default_factory=list)
@@ -0,0 +1,19 @@
1
+ import pymxbi
2
+ from loguru import logger
3
+ from pymxbi import MXBI, MXBIModel
4
+
5
+ from .config_store import ConfigStore
6
+ from .models.session import SessionConfig
7
+
8
+
9
+ def build_mxbi(mxbi_config_path, session_config_path) -> MXBI:
10
+
11
+ mxbi_config = ConfigStore(mxbi_config_path, MXBIModel).value
12
+ session_config = ConfigStore(session_config_path, SessionConfig).value
13
+
14
+ mxbi = pymxbi.build_mxbi(mxbi_config, logger)
15
+ mxbi.register_animal(
16
+ {animal.rfid_id: animal.name for animal in session_config.animals}
17
+ )
18
+
19
+ return mxbi
@@ -31,10 +31,6 @@ MOUNT_SERVICE_PATH = SERVICE_DIR_PATH / MOUNT_SERVICE_NAME
31
31
  SYNC_SERVICE_NAME = "sync.service"
32
32
  SYNC_SERVICE_PATH = SERVICE_DIR_PATH / SYNC_SERVICE_NAME
33
33
 
34
- MXBI_CONFIG_PATH = CONFIG_DIR_PATH / "mxbi.json"
35
- SESSION_CONFIG_PATH = CONFIG_DIR_PATH / "session.json"
36
- OPTIONS_PATH = CONFIG_DIR_PATH / "options.json"
37
- STAGE_PATH = CONFIG_DIR_PATH / "stage.json"
38
34
  SESSION_COUNTER_PATH = CONFIG_DIR_PATH / "session_counter.json"
39
35
 
40
36
  ASSETS_DIR_PATH = ROOT_DIR_PATH / "assets"
@@ -1,8 +1,7 @@
1
- from .scene_manager import SceneManager, Scenes
1
+ from .scene_manager import SceneManager
2
2
  from .scene_protocol import SceneProtocol
3
3
 
4
4
  __all__ = [
5
5
  "SceneManager",
6
- "Scenes",
7
6
  "SceneProtocol",
8
7
  ]
@@ -1,34 +1,39 @@
1
1
  from pathlib import Path
2
2
 
3
- from pydantic import RootModel
4
3
  from pygame import Event, Surface
5
4
 
5
+ from ..config_store import ConfigStore
6
+ from ..models.session import Options
6
7
  from .scene_protocol import SceneProtocol
7
8
 
8
9
 
9
- class Scenes(RootModel):
10
- root: list[str]
11
-
12
-
13
10
  class SceneManager:
14
- scenes: dict[str, type[SceneProtocol]] = {}
11
+ _scenes: dict[str, type[SceneProtocol]] = {}
15
12
 
16
13
  def __init__(self) -> None:
17
14
  self.current: SceneProtocol | None = None
18
15
  self._pending: SceneProtocol | None = None
19
16
 
20
17
  def persist(self, path: Path) -> None:
21
- scenes = Scenes(root=list(self.scenes.keys()))
22
- json_data = scenes.model_dump_json()
23
-
24
- with path.open("w") as f:
25
- f.write(json_data)
26
-
27
- def register(self, scene: type[SceneProtocol], name: str | None = None) -> None:
28
- if name is None:
29
- name = scene.__name__.lower()
18
+ options_store = ConfigStore(path, Options)
19
+
20
+ options_store.value.stages = list(self._scenes.keys())
21
+ options_store.save()
22
+
23
+ def register(
24
+ self, scene: dict[str, type[SceneProtocol]] | list[type[SceneProtocol]]
25
+ ) -> None:
26
+ if isinstance(scene, dict):
27
+ self._scenes.update(scene)
28
+ elif isinstance(scene, list):
29
+ for s in scene:
30
+ self._scenes[s.__name__.lower()] = s
31
+ else:
32
+ raise ValueError("Invalid scene type")
30
33
 
31
- self.scenes[name] = scene
34
+ @property
35
+ def scenes(self) -> dict[str, type[SceneProtocol]]:
36
+ return self._scenes
32
37
 
33
38
  def switch(self, scene: type[SceneProtocol], defer: bool = True) -> None:
34
39
  if defer:
@@ -1,17 +1,15 @@
1
1
  from PySide6.QtCore import Qt, Signal
2
2
  from PySide6.QtWidgets import QComboBox, QFormLayout, QLabel, QLineEdit, QMenu
3
3
 
4
- from ...config_store import ConfigStore
5
4
  from ...models.animal import AnimalConfig
6
- from ...path import STAGE_PATH
7
- from ...scene import Scenes
5
+ from ...models.session import Options
8
6
  from .card import CardFrame
9
7
 
10
8
 
11
9
  class AnimalCard(CardFrame):
12
10
  remove_requested = Signal()
13
11
 
14
- def __init__(self, parent, animals: dict[str, str]):
12
+ def __init__(self, parent, animals: dict[str, str], options: Options):
15
13
  super().__init__(parent=parent, object_name="card")
16
14
  self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
17
15
  self.customContextMenuRequested.connect(self._on_context_menu)
@@ -36,9 +34,9 @@ class AnimalCard(CardFrame):
36
34
  layout.addRow(lable_animal_id, self.line_animal_id)
37
35
 
38
36
  label_stage = QLabel("stage", self)
39
- items = ConfigStore(STAGE_PATH, Scenes).value
37
+ items = options.stages
40
38
  self.combo_stage = QComboBox(self)
41
- self.combo_stage.addItems([i for i in items.root])
39
+ self.combo_stage.addItems(items)
42
40
  self.combo_stage.setCurrentText("idle")
43
41
  layout.addRow(label_stage, self.combo_stage)
44
42
 
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from PySide6.QtCore import Qt
4
2
  from PySide6.QtWidgets import (
5
3
  QComboBox,
@@ -12,7 +10,7 @@ from PySide6.QtWidgets import (
12
10
  )
13
11
 
14
12
  from ...models.animal import AnimalConfig
15
- from ...models.session import RewardEnum, SessionConfig
13
+ from ...models.session import Options, RewardEnum, SessionConfig
16
14
  from .animal import AnimalCard
17
15
 
18
16
 
@@ -51,10 +49,11 @@ class ExperimentConfigGroup(QGroupBox):
51
49
 
52
50
 
53
51
  class ExperimentAnimalsGroup(QGroupBox):
54
- def __init__(self, parent=None, *, animals: dict[str, str]):
52
+ def __init__(self, parent=None, *, animals: dict[str, str], options: Options):
55
53
  super().__init__("Animals", parent)
56
54
 
57
55
  self._animals = animals
56
+ self._options = options
58
57
  self.layout_animals = QGridLayout(self)
59
58
  self.setLayout(self.layout_animals)
60
59
 
@@ -68,7 +67,7 @@ class ExperimentAnimalsGroup(QGroupBox):
68
67
  menu.exec(self.mapToGlobal(pos))
69
68
 
70
69
  def _on_add_animal(self):
71
- animal_card = AnimalCard(self, self._animals)
70
+ animal_card = AnimalCard(self, self._animals, self._options)
72
71
  animal_card.remove_requested.connect(
73
72
  lambda _card=animal_card: self._on_remove_animal(_card)
74
73
  )
@@ -103,7 +102,7 @@ class ExperimentAnimalsGroup(QGroupBox):
103
102
 
104
103
  def load_config(self, config: SessionConfig):
105
104
  for animal_configs in config.animals:
106
- animal_card = AnimalCard(self, self._animals)
105
+ animal_card = AnimalCard(self, self._animals, self._options)
107
106
  animal_card.load_config(animal_configs)
108
107
  animal_card.remove_requested.connect(
109
108
  lambda _card=animal_card: self._on_remove_animal(_card)
@@ -1,6 +1,7 @@
1
+ from pathlib import Path
2
+
1
3
  from PySide6.QtCore import Signal
2
4
  from PySide6.QtWidgets import (
3
- QApplication,
4
5
  QHBoxLayout,
5
6
  QMainWindow,
6
7
  QPushButton,
@@ -10,17 +11,16 @@ from PySide6.QtWidgets import (
10
11
 
11
12
  from ..config_store import ConfigStore
12
13
  from ..models.session import Options, SessionConfig
13
- from ..path import OPTIONS_PATH, SESSION_CONFIG_PATH
14
14
  from .components.experiment_groups import ExperimentAnimalsGroup, ExperimentConfigGroup
15
15
 
16
16
 
17
17
  class ExperimentPanel(QMainWindow):
18
18
  accepted = Signal()
19
19
 
20
- def __init__(self, parent=None):
21
- super().__init__(parent)
22
- self._config = ConfigStore(SESSION_CONFIG_PATH, SessionConfig)
23
- self._options = ConfigStore(OPTIONS_PATH, Options)
20
+ def __init__(self, session_config_path: Path, options_path: Path):
21
+ super().__init__()
22
+ self._config = ConfigStore(session_config_path, SessionConfig)
23
+ self._options = ConfigStore(options_path, Options)
24
24
 
25
25
  self.setWindowTitle("Experiment Panel")
26
26
 
@@ -36,7 +36,7 @@ class ExperimentPanel(QMainWindow):
36
36
  layout_main.addWidget(self.group_config)
37
37
 
38
38
  self.group_animals = ExperimentAnimalsGroup(
39
- self, animals=self._options.value.animals
39
+ self, animals=self._options.value.animals, options=self._options.value
40
40
  )
41
41
  layout_main.addWidget(self.group_animals)
42
42
 
@@ -80,12 +80,3 @@ class ExperimentPanel(QMainWindow):
80
80
  self._on_save()
81
81
  self.close()
82
82
  self.accepted.emit()
83
-
84
-
85
- if __name__ == "__main__":
86
- import sys
87
-
88
- app = QApplication(sys.argv)
89
- experiment_panel = ExperimentPanel()
90
- experiment_panel.show()
91
- sys.exit(app.exec())
@@ -1,9 +1,10 @@
1
+ from pathlib import Path
2
+
1
3
  from pymxbi import MXBIModel
2
4
  from pymxbi.detector import DetectorEnum, DetectorModel
3
5
  from pymxbi.rewarder import RewarderEnum, RewarderModel
4
6
  from PySide6.QtCore import Signal
5
7
  from PySide6.QtWidgets import (
6
- QApplication,
7
8
  QHBoxLayout,
8
9
  QMainWindow,
9
10
  QPushButton,
@@ -13,7 +14,6 @@ from PySide6.QtWidgets import (
13
14
 
14
15
  from ..config_store import ConfigStore
15
16
  from ..models.session import Options
16
- from ..path import MXBI_CONFIG_PATH, OPTIONS_PATH
17
17
  from .components.baseconfig import BaseConfig
18
18
  from .components.device_card import (
19
19
  BeambreakDetectorCard,
@@ -44,10 +44,10 @@ class MXBIPanel(QMainWindow):
44
44
  # Lifecycle / Init
45
45
  # -----------------------------
46
46
 
47
- def __init__(self):
47
+ def __init__(self, mxbi_config_path: Path, options_path: Path):
48
48
  super().__init__()
49
- self._config = ConfigStore(MXBI_CONFIG_PATH, MXBIModel)
50
- self._options = ConfigStore(OPTIONS_PATH, Options)
49
+ self._config = ConfigStore(mxbi_config_path, MXBIModel)
50
+ self._options = ConfigStore(options_path, Options)
51
51
 
52
52
  self._build_ui()
53
53
  self._load_from_config()
@@ -141,12 +141,3 @@ class MXBIPanel(QMainWindow):
141
141
 
142
142
  def _on_cancel(self) -> None:
143
143
  self.close()
144
-
145
-
146
- if __name__ == "__main__":
147
- import sys
148
-
149
- app = QApplication(sys.argv)
150
- window = MXBIPanel()
151
- window.show()
152
- sys.exit(app.exec())
@@ -0,0 +1,25 @@
1
+ from pathlib import Path
2
+
3
+ from .experiment_panel import ExperimentPanel
4
+ from .mxbi_panel import MXBIPanel
5
+
6
+
7
+ def config_wizard(
8
+ mxbi_config_path: Path,
9
+ session_config_path: Path,
10
+ options_path: Path,
11
+ ):
12
+ import sys
13
+
14
+ from PySide6.QtWidgets import QApplication
15
+
16
+ app = QApplication(sys.argv)
17
+
18
+ mxbi_panel = MXBIPanel(mxbi_config_path, options_path)
19
+ experiment_panel = ExperimentPanel(session_config_path, options_path)
20
+ mxbi_panel.accepted.connect(experiment_panel.show)
21
+ experiment_panel.accepted.connect(app.quit)
22
+
23
+ mxbi_panel.show()
24
+
25
+ app.exec()
@@ -0,0 +1,35 @@
1
+ from pathlib import Path
2
+
3
+ from ..config_store import ConfigStore
4
+ from ..models.animal import Animal, StageState
5
+ from ..models.session import DailySessionIdStore, Session, SessionConfig
6
+
7
+
8
+ def init_session(session_config_path: Path, session_counter_path: Path) -> Session:
9
+ session_config = ConfigStore(session_config_path, SessionConfig).value
10
+ store = DailySessionIdStore(session_counter_path)
11
+
12
+ animal_dict: dict[str, Animal] = {}
13
+ for animal_config in session_config.animals:
14
+ train_state = StageState(
15
+ stage_name=animal_config.stage, level=animal_config.level
16
+ )
17
+ animal_state = Animal(
18
+ rfid_id=animal_config.rfid_id,
19
+ name=animal_config.name,
20
+ )
21
+ animal_state.set_current_stage(train_state)
22
+ animal_dict[animal_config.name] = animal_state
23
+
24
+ session = Session(
25
+ session_id=store.session_id,
26
+ experimenter=session_config.experimenter,
27
+ reward_type=session_config.reward_type,
28
+ send_email=False,
29
+ sync_data=False,
30
+ note=session_config.note,
31
+ animals=animal_dict,
32
+ )
33
+ session.start()
34
+
35
+ return session
@@ -1,3 +0,0 @@
1
- from .mxbiflow import MXBIFlow, get_mxbiflow
2
-
3
- __all__ = ["MXBIFlow", "get_mxbiflow"]
@@ -1,4 +0,0 @@
1
- from .habituation.habituarion import Habituarion
2
- from .idle.idle import IDLE
3
-
4
- __all__ = ["Habituarion", "IDLE"]
@@ -1,106 +0,0 @@
1
- from pymxbi import MXBI
2
-
3
- from .game import Game
4
- from .models.session import Session
5
-
6
-
7
- def main():
8
- run_config()
9
-
10
- mxbi = build_mxbi()
11
-
12
- session = init_session()
13
-
14
- game = init_mxbiflow(mxbi, session)
15
- game.play()
16
-
17
-
18
- def run_config():
19
- import sys
20
-
21
- from PySide6.QtWidgets import QApplication
22
-
23
- from .ui.experiment_panel import ExperimentPanel
24
- from .ui.mxbi_panel import MXBIPanel
25
-
26
- app = QApplication(sys.argv)
27
-
28
- mxbi_panel = MXBIPanel()
29
- experiment_panel = ExperimentPanel()
30
- mxbi_panel.accepted.connect(experiment_panel.show)
31
- experiment_panel.accepted.connect(app.quit)
32
-
33
- mxbi_panel.show()
34
-
35
- app.exec()
36
-
37
-
38
- def build_mxbi() -> MXBI:
39
- from loguru import logger
40
- from pymxbi import MXBIModel, build_mxbi
41
-
42
- from .config_store import ConfigStore
43
- from .models.session import SessionConfig
44
- from .path import MXBI_CONFIG_PATH, SESSION_CONFIG_PATH
45
-
46
- mxbi_config = ConfigStore(MXBI_CONFIG_PATH, MXBIModel).value
47
- session_config = ConfigStore(SESSION_CONFIG_PATH, SessionConfig).value
48
-
49
- mxbi = build_mxbi(mxbi_config, logger)
50
- mxbi.register_animal(
51
- {animal.rfid_id: animal.name for animal in session_config.animals}
52
- )
53
-
54
- return mxbi
55
-
56
-
57
- def init_session() -> Session:
58
- from .config_store import ConfigStore
59
- from .models.animal import Animal, StageState
60
- from .models.session import DailySessionIdStore, Session, SessionConfig
61
- from .path import SESSION_CONFIG_PATH, SESSION_COUNTER_PATH
62
-
63
- session_config = ConfigStore(SESSION_CONFIG_PATH, SessionConfig).value
64
- store = DailySessionIdStore(SESSION_COUNTER_PATH)
65
-
66
- animal_dict: dict[str, Animal] = {}
67
- for animal_config in session_config.animals:
68
- train_state = StageState(
69
- stage_name=animal_config.stage, level=animal_config.level
70
- )
71
- animal_state = Animal(
72
- rfid_id=animal_config.rfid_id,
73
- name=animal_config.name,
74
- )
75
- animal_state.set_current_stage(train_state)
76
- animal_dict[animal_config.name] = animal_state
77
-
78
- session = Session(
79
- session_id=store.session_id,
80
- experimenter=session_config.experimenter,
81
- reward_type=session_config.reward_type,
82
- send_email=False,
83
- sync_data=False,
84
- note=session_config.note,
85
- animals=animal_dict,
86
- )
87
- session.start()
88
- print(session.session_id)
89
-
90
- return session
91
-
92
-
93
- def init_mxbiflow(mxbi, session) -> Game:
94
- from .default import IDLE, Habituarion
95
- from .detector_bridge import DetectorBridge
96
- from .GNGSiD import SizeReduction
97
- from .path import STAGE_PATH
98
- from .scene import SceneManager
99
-
100
- scene_manager = SceneManager()
101
- scene_manager.register(Habituarion)
102
- scene_manager.register(IDLE)
103
- scene_manager.register(SizeReduction)
104
- scene_manager.persist(STAGE_PATH)
105
- detector_bridge = DetectorBridge(mxbi.detector)
106
- return Game(session, scene_manager, detector_bridge, mxbi)
File without changes
File without changes