sl-shared-assets 5.0.1__tar.gz → 5.1.1__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.

Potentially problematic release.


This version of sl-shared-assets might be problematic. Click here for more details.

Files changed (37) hide show
  1. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/PKG-INFO +1 -1
  2. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_lin.yml +3 -3
  3. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_lin_spec.txt +4 -4
  4. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/pyproject.toml +1 -1
  5. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/__init__.py +7 -0
  6. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/command_line_interfaces/manage.py +57 -2
  7. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/data_classes/__init__.py +3 -3
  8. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/data_classes/configuration_data.py +105 -138
  9. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/data_classes/runtime_data.py +2 -4
  10. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/data_classes/session_data.py +116 -86
  11. sl_shared_assets-5.1.1/src/sl_shared_assets/data_classes/surgery_data.py +152 -0
  12. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/server/__init__.py +1 -2
  13. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/server/job.py +43 -50
  14. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/server/pipeline.py +108 -119
  15. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/server/server.py +45 -104
  16. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/tools/__init__.py +4 -0
  17. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/tools/packaging_tools.py +1 -1
  18. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/tools/project_management_tools.py +67 -12
  19. sl_shared_assets-5.0.1/src/sl_shared_assets/data_classes/surgery_data.py +0 -152
  20. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/.gitignore +0 -0
  21. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/LICENSE +0 -0
  22. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/README.md +0 -0
  23. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/Makefile +0 -0
  24. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/make.bat +0 -0
  25. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/source/api.rst +0 -0
  26. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/source/conf.py +0 -0
  27. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/source/index.rst +0 -0
  28. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/docs/source/welcome.rst +0 -0
  29. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_osx.yml +0 -0
  30. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_osx_spec.txt +0 -0
  31. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_win.yml +0 -0
  32. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/envs/slsa_dev_win_spec.txt +0 -0
  33. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/command_line_interfaces/__init__.py +0 -0
  34. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/command_line_interfaces/configure.py +0 -0
  35. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/py.typed +0 -0
  36. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/src/sl_shared_assets/tools/transfer_tools.py +0 -0
  37. {sl_shared_assets-5.0.1 → sl_shared_assets-5.1.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sl-shared-assets
3
- Version: 5.0.1
3
+ Version: 5.1.1
4
4
  Summary: Provides data acquisition and processing assets shared between Sun (NeuroAI) lab libraries.
5
5
  Project-URL: Homepage, https://github.com/Sun-Lab-NBB/sl-shared-assets
6
6
  Project-URL: Documentation, https://sl-shared-assets-api-docs.netlify.app/
@@ -6,7 +6,7 @@ dependencies:
6
6
  - _openmp_mutex=4.5=2_gnu
7
7
  - bzip2=1.0.8=h4bc722e_7
8
8
  - ca-certificates=2025.8.3=hbd8a1cb_0
9
- - cachetools=6.1.0=pyhd8ed1ab_0
9
+ - cachetools=6.2.0=pyhd8ed1ab_0
10
10
  - chardet=5.2.0=pyhd8ed1ab_3
11
11
  - colorama=0.4.6=pyhd8ed1ab_1
12
12
  - distlib=0.4.0=pyhd8ed1ab_0
@@ -31,7 +31,7 @@ dependencies:
31
31
  - pluggy=1.6.0=pyhd8ed1ab_0
32
32
  - pyproject-api=1.9.1=pyhe01879c_0
33
33
  - python=3.13.5=hec9711d_102_cp313
34
- - python-uv=0.8.11=pyhe01879c_0
34
+ - python-uv=0.8.13=pyhcf101f3_0
35
35
  - python_abi=3.13=8_cp313
36
36
  - readline=8.2=h8c095d6_2
37
37
  - tk=8.6.13=noxft_hd72426e_102
@@ -40,6 +40,6 @@ dependencies:
40
40
  - tox-uv=1.28.0=pyhd8ed1ab_0
41
41
  - typing_extensions=4.14.1=pyhe01879c_0
42
42
  - tzdata=2025b=h78e105d_0
43
- - uv=0.8.11=heb9285d_0
43
+ - uv=0.8.13=heb9285d_0
44
44
  - virtualenv=20.34.0=pyhd8ed1ab_0
45
45
 
@@ -1,10 +1,10 @@
1
- List of packages in environment: "/home/cybermouse/miniforge3/envs/slsa_dev_lin"
1
+ List of packages in environment: "/home/cyberaxolotl/miniforge3/envs/slsa_dev_lin"
2
2
 
3
3
  https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2
4
4
  https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2
5
5
  https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda
6
6
  https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda
7
- https://conda.anaconda.org/conda-forge/noarch/cachetools-6.1.0-pyhd8ed1ab_0.conda
7
+ https://conda.anaconda.org/conda-forge/noarch/cachetools-6.2.0-pyhd8ed1ab_0.conda
8
8
  https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda
9
9
  https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
10
10
  https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
@@ -29,7 +29,7 @@ https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.co
29
29
  https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda
30
30
  https://conda.anaconda.org/conda-forge/noarch/pyproject-api-1.9.1-pyhe01879c_0.conda
31
31
  https://conda.anaconda.org/conda-forge/linux-64/python-3.13.5-hec9711d_102_cp313.conda
32
- https://conda.anaconda.org/conda-forge/noarch/python-uv-0.8.11-pyhe01879c_0.conda
32
+ https://conda.anaconda.org/conda-forge/noarch/python-uv-0.8.13-pyhcf101f3_0.conda
33
33
  https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda
34
34
  https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda
35
35
  https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda
@@ -38,5 +38,5 @@ https://conda.anaconda.org/conda-forge/noarch/tox-4.28.4-pyhe01879c_0.conda
38
38
  https://conda.anaconda.org/conda-forge/noarch/tox-uv-1.28.0-pyhd8ed1ab_0.conda
39
39
  https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda
40
40
  https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda
41
- https://conda.anaconda.org/conda-forge/linux-64/uv-0.8.11-heb9285d_0.conda
41
+ https://conda.anaconda.org/conda-forge/linux-64/uv-0.8.13-heb9285d_0.conda
42
42
  https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.34.0-pyhd8ed1ab_0.conda
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
  # Project metdata section. Provides the genral ID information about the project.
7
7
  [project]
8
8
  name = "sl-shared-assets"
9
- version = "5.0.1"
9
+ version = "5.1.1"
10
10
  description = "Provides data acquisition and processing assets shared between Sun (NeuroAI) lab libraries."
11
11
  readme = "README.md"
12
12
  license = { file = "LICENSE" }
@@ -9,6 +9,8 @@ from ataraxis_base_utilities import console
9
9
 
10
10
  from .tools import (
11
11
  ProjectManifest,
12
+ acquire_lock,
13
+ release_lock,
12
14
  delete_directory,
13
15
  transfer_directory,
14
16
  generate_project_manifest,
@@ -84,6 +86,9 @@ __all__ = [
84
86
  "MesoscopeSystemConfiguration",
85
87
  "ProcedureData",
86
88
  "ProcessedData",
89
+ "ProcessingPipeline",
90
+ "ProcessingPipelines",
91
+ "ProcessingStatus",
87
92
  "ProcessingTracker",
88
93
  "ProjectManifest",
89
94
  "RawData",
@@ -98,6 +103,7 @@ __all__ = [
98
103
  "TrackerFileNames",
99
104
  "WindowCheckingDescriptor",
100
105
  "ZaberPositions",
106
+ "acquire_lock",
101
107
  "calculate_directory_checksum",
102
108
  "delete_directory",
103
109
  "generate_manager_id",
@@ -105,5 +111,6 @@ __all__ = [
105
111
  "get_credentials_file_path",
106
112
  "get_system_configuration_data",
107
113
  "get_working_directory",
114
+ "release_lock",
108
115
  "transfer_directory",
109
116
  ]
@@ -8,6 +8,8 @@ import click
8
8
  from ataraxis_base_utilities import LogLevel, console
9
9
 
10
10
  from ..tools import (
11
+ acquire_lock,
12
+ release_lock,
11
13
  archive_session,
12
14
  prepare_session,
13
15
  resolve_checksum,
@@ -35,8 +37,10 @@ def manage() -> None:
35
37
  "--session-path",
36
38
  type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
37
39
  required=True,
38
- help="The absolute path to the root session directory to process. This directory must contain the 'raw_data' "
39
- "subdirectory.",
40
+ help=(
41
+ "The absolute path to the root session directory to process. This directory must contain the 'raw_data' "
42
+ "subdirectory."
43
+ ),
40
44
  )
41
45
  @click.option(
42
46
  "-pdr",
@@ -83,6 +87,57 @@ def manage_session(
83
87
  ctx.obj["reset_tracker"] = reset_tracker
84
88
 
85
89
 
90
+ # noinspection PyUnresolvedReferences
91
+ @manage_session.command("lock")
92
+ @click.pass_context
93
+ def lock_session(ctx: Any) -> None:
94
+ """Acquires the lock for the target session's data.
95
+
96
+ This command is used to ensure that the target session's data can only be accessed from the specified manager
97
+ process. Calling this command is a prerequisite for all other session data management, processing, or dataset
98
+ formation commands. If this command is called as part of runtime, the 'unlock' command must be called at the end
99
+ of that runtime to properly release the session's data lock. This command respects the '--reset-tracker' flag of the
100
+ 'session' command group and, if this flag is present, forcibly resets the session lock file before re-acquiring it
101
+ for the specified manager process.
102
+ """
103
+
104
+ # Extracts shared parameters from context
105
+ session_path = ctx.obj["session_path"]
106
+ processed_data_root = ctx.obj["processed_data_root"]
107
+ manager_id = ctx.obj["manager_id"]
108
+ reset_tracker = ctx.obj["reset_tracker"]
109
+
110
+ acquire_lock(
111
+ session_path=session_path,
112
+ manager_id=manager_id,
113
+ processed_data_root=processed_data_root,
114
+ reset_lock=reset_tracker,
115
+ )
116
+
117
+
118
+ # noinspection PyUnresolvedReferences
119
+ @manage_session.command("unlock")
120
+ @click.pass_context
121
+ def unlock_session(ctx: Any) -> None:
122
+ """Releases the lock for the target session's data.
123
+
124
+ This command is used to reverse the effect of the 'lock' command, allowing other manager processes to work with
125
+ the session's data. This command can only be called from the same manager process used to acquire the
126
+ session's data lock.
127
+ """
128
+
129
+ # Extracts shared parameters from context
130
+ session_path = ctx.obj["session_path"]
131
+ processed_data_root = ctx.obj["processed_data_root"]
132
+ manager_id = ctx.obj["manager_id"]
133
+
134
+ release_lock(
135
+ session_path=session_path,
136
+ manager_id=manager_id,
137
+ processed_data_root=processed_data_root,
138
+ )
139
+
140
+
86
141
  # noinspection PyUnresolvedReferences
87
142
  @manage_session.command("checksum")
88
143
  @click.pass_context
@@ -1,6 +1,6 @@
1
- """This package provides the classes used to store data acquired at all stages of the Sun lab data workflow and to
2
- configure various elements and pipelines making up the overall workflow. Many classes in this package are designed to
3
- be saved to disk as .yaml files and restored from the .yaml files as needed."""
1
+ """This package provides the classes used to store data acquired in the Sun lab and to configure all elements and
2
+ pipelines making up the lab's data workflow. Many classes from this package are designed to be saved to disk as .yaml
3
+ files and restored from the .yaml files as needed."""
4
4
 
5
5
  from .runtime_data import (
6
6
  ZaberPositions,
@@ -1,6 +1,4 @@
1
- """This module provides classes used to configure data acquisition and processing runtimes in the Sun lab. The assets
2
- exposed by this module are used to configure specific hardware components used to acquire data and interface
3
- with the remote hardware (servers) used to store, process, and analyze data."""
1
+ """This module provides classes used to configure data acquisition and processing runtimes in the Sun lab."""
4
2
 
5
3
  import copy
6
4
  from enum import StrEnum
@@ -15,7 +13,7 @@ from ..server import ServerCredentials
15
13
 
16
14
 
17
15
  class AcquisitionSystems(StrEnum):
18
- """Defines the set of data acquisition systems used in the Sun lab and supported by all data-related libraries."""
16
+ """Stores the names for all data acquisition systems currently used in the Sun lab."""
19
17
 
20
18
  MESOSCOPE_VR = "mesoscope-vr"
21
19
  """The Mesoscope-VR data acquisition system. It is built around 2-Photon Random Access Mesoscope (2P-RAM) and
@@ -24,113 +22,97 @@ class AcquisitionSystems(StrEnum):
24
22
 
25
23
  @dataclass()
26
24
  class ExperimentState:
27
- """Encapsulates the information used to set and maintain the desired experiment and system state.
25
+ """Stores the information used to set and maintain the desired experiment and system state.
28
26
 
29
- Broadly, each experiment runtime can be conceptualized as a two-state-system. The first is the experiment task,
30
- which reflects the behavior goal, the rules for achieving the goal, and the reward for achieving the goal. The
31
- second is the data acquisition system state, which is a snapshot of all hardware module states that make up the
32
- system that acquires the data and controls the task environment. Overall, the experiment state is about
33
- 'what the animal is doing', while the system state is about 'what the hardware is doing'.
27
+ Broadly, each experiment runtime can be conceptualized as a two-state system. The first is the experiment task
28
+ state, which reflects the behavior goal, the rules for achieving the goal, and the reward for achieving the goal.
29
+ The second is the data acquisition system state, which is a snapshot of all hardware module states that make up the
30
+ system that acquires the data and controls the task environment.
34
31
 
35
32
  Note:
36
- This class is acquisition-system-agnostic. It can be used to define the ExperimentConfiguration class for any
37
- valid data acquisition system.
33
+ This class is acquisition-system-agnostic. All data acquisition systems use this class as part of their specific
34
+ ExperimentConfiguration class instances.
38
35
  """
39
36
 
40
37
  experiment_state_code: int
41
- """The integer code of the experiment state. Experiment states do not have a predefined meaning, Instead, each
42
- project is expected to define and follow its own experiment state code mapping. Typically, the experiment state
43
- code is used to denote major experiment stages, such as 'baseline', 'task', 'cooldown', etc. Note, the same
44
- experiment state code can be used by multiple sequential ExperimentState instances to change the system states
45
- while maintaining the same experiment state."""
38
+ """The integer code of the experiment state. Note, each experiment is expected to define and follow its own
39
+ experiment state code mapping. Typically, the experiment state code is used to denote major experiment stages,
40
+ such as 'baseline', 'task', 'cooldown', etc. The same experiment state code can be used by multiple sequential
41
+ ExperimentState instances to change the data acquisition system states while maintaining the same experiment
42
+ state."""
46
43
  system_state_code: int
47
- """One of the supported system state-codes. Note, the meaning of each system state code depends on the specific
48
- data acquisition and experiment control system used by the project. For details on available system-states, see
49
- the sl-experiment library documentation."""
44
+ """One of the supported data acquisition system state-codes. Note, the meaning of each system state code depends on
45
+ the specific data acquisition system used during the experiment."""
50
46
  state_duration_s: float
51
- """The time, in seconds, to maintain the experiment and system state combination specified by this instance."""
47
+ """The time, in seconds, to maintain the experiment and system state combination specified by this instance during
48
+ runtime."""
52
49
  initial_guided_trials: int
53
- """The number of trials (laps) at the onset of the experiment state, for which to enable lick guidance. This
54
- determines the number of trials, counting from the onset of the experiment state, for which the animal will receive
55
- water rewards from entering the reward zone. Once the specified number of guided trial passes, the system disables
56
- guidance, requiring the animal to lick in the reward zone to get water rewards."""
50
+ """The number of trials (laps), counting from the onset of the experiment state, during which the animal should
51
+ receive water rewards for entering the reward zone. Once the specified number of guided trials passes, the system
52
+ disables guidance, requiring the animal to lick in the reward zone to get rewards."""
57
53
  recovery_failed_trial_threshold: int
58
- """Specifies the number of failed (non-rewarded) trials (laps), after which the system will re-enable lick guidance
59
- for the 'recovery_guided_trials' number of following trials. Note, engaging the recovery guided trial system
60
- requires the specified number of failed trials to occur sequentially."""
54
+ """The number of sequentially failed (non-rewarded) trials (laps), after which the system should
55
+ re-enable lick guidance for the following 'recovery_guided_trials' number of trials."""
61
56
  recovery_guided_trials: int
62
- """Specifies the number of trials (laps) for which the system should re-enable lick guidance, when the animal
57
+ """The number of trials (laps) for which the system should re-enable lick guidance, when the animal
63
58
  sequentially fails 'failed_trial_threshold' number of trials. This field works similar to the
64
59
  'initial_guided_trials' field, but is triggered by repeated performance failures, rather than experiment state
65
- onset. After the animal runs this many guided trials, the system automatically disables guidance for the following
66
- trials."""
60
+ onset."""
67
61
 
68
62
 
69
63
  @dataclass()
70
64
  class ExperimentTrial:
71
- """Encapsulates information about a single experiment trial.
65
+ """Stores the information about a single experiment trial.
72
66
 
73
- All Virtual Reality tasks can be broadly conceptualized as repeating motifs (sequences) of wall cues,
74
- associated with a specific goal, for which animals receive water rewards. Since some experiments can use multiple
75
- trial types as part of the same experiment session, multiple instances of this class can be used to specify
76
- supported trial structures and trial parameters for a given experiment.
67
+ All Virtual Reality (VR) tasks can be broadly conceptualized as repeating motifs (sequences) of VR environment wall
68
+ cues, associated with a specific goal, for which animals receive water rewards. Each complete motif is typically
69
+ interpreted as a single experiment trial.
70
+
71
+ Notes:
72
+ Since some experiments use multiple distinct trial types as part of the same experiment session, multiple
73
+ instances of this class can be used by an ExperimentConfiguration class instance to represent multiple used
74
+ trial types.
77
75
  """
78
76
 
79
77
  cue_sequence: list[int]
80
- """Specifies the sequence of wall cues experienced by the animal while running this trial. Note, the cues must be
81
- specified as integer-codes, where each code has the same meaning as in the 'cue_map' dictionary of the main
82
- ExperimentConfiguration class for that experiment."""
78
+ """The sequence of Virtual Reality environment wall cues experienced by the animal while running this
79
+ trial. Note, the cues must be specified as integer-codes matching the codes used in the 'cue_map' dictionary of the
80
+ ExperimentConfiguration class for the experiment."""
83
81
  trial_length_cm: float
84
82
  """The length of the trial cue sequence in centimeters."""
85
83
  trial_reward_size_ul: float
86
- """The volume of water, in microliters, to be dispensed when the animal successfully completes the trial task."""
84
+ """The volume of water, in microliters, dispensed when the animal successfully completes the trial's task."""
87
85
  reward_zone_start_cm: float
88
- """Specifies the starting boundary of the trial reward zone, in centimeters."""
86
+ """The starting boundary of the trial reward zone, in centimeters."""
89
87
  reward_zone_end_cm: float
90
- """Specifies the ending boundary of the trial reward zone, in centimeters."""
88
+ """The ending boundary of the trial reward zone, in centimeters."""
91
89
  guidance_trigger_location_cm: float
92
- """Specifies the location of the invisible boundary (wall) with which the animal must collide to elicit automated
93
- water reward during guided trials."""
90
+ """The location of the invisible boundary (wall) with which the animal must collide to trigger water reward
91
+ delivery during guided trials."""
94
92
 
95
93
 
96
94
  # noinspection PyArgumentList
97
95
  @dataclass()
98
96
  class MesoscopeExperimentConfiguration(YamlConfig):
99
- """Stores the configuration of a single experiment runtime that uses the Mesoscope_VR data acquisition system.
100
-
101
- Primarily, this includes the sequence of experiment and system states that define the flow of the experiment
102
- runtime and the configuration of various trials supported by the experiment runtime. During runtime, the main
103
- runtime control function traverses the sequence of states stored in this class instance start-to-end in the exact
104
- order specified by the user. Together with custom Unity projects, which define the task logic (how the system
105
- responds to animal interactions with the VR system), this class allows flexibly implementing a wide range of
106
- experiments using the Mesoscope-VR system.
107
-
108
- Each project should define one or more experiment configurations and save them as .yaml files inside the project
109
- 'configuration' folder. The name for each configuration file is defined by the user and is used to identify and load
110
- the experiment configuration when the 'sl-experiment' CLI command exposed by the sl-experiment library is executed.
97
+ """Stores the configuration of an experiment runtime that uses the Mesoscope_VR data acquisition system.
111
98
 
112
- Notes:
113
- This class is designed exclusively for the Mesoscope-VR system. Any other system needs to define a separate
114
- ExperimentConfiguration class to specify its experiment runtimes and additional data.
115
-
116
- To create a new experiment configuration, use the 'sl-create-experiment' CLI command.
99
+ During runtime, the acquisition system executes the sequence of states stored in this class instance. Together with
100
+ custom Unity projects, which define the task environment and logic, this class allows flexibly implementing a wide
101
+ range of experiments using the Mesoscope-VR system.
117
102
  """
118
103
 
119
104
  cue_map: dict[int, float] = field(default_factory=lambda: {0: 30.0, 1: 30.0, 2: 30.0, 3: 30.0, 4: 30.0})
120
- """A dictionary that maps each integer-code associated with a wall cue used in the Virtual Reality experiment
121
- environment to its length in real-world centimeters. It is used to map each VR cue to the distance the animal needs
105
+ """Maps each integer-code associated with the experiment's Virtual Reality (VR) environment wall
106
+ cue to its length in real-world centimeters. It is used to map each VR cue to the distance the animal needs
122
107
  to travel to fully traverse the wall cue region from start to end."""
123
108
  cue_offset_cm: float = 10.0
124
- """Specifies the positive offset distance, in centimeters, by which the animal's running track is shifted
125
- relative to VR wall cue sequence. Due to how the VR environment is revealed to the animal, most runtimes
126
- need to shift the animal slightly forward relative to the VR cue sequence origin (0), to prevent it from seeing the
127
- area before the first VR wall cue when the task starts and when the animal is teleported to the beginning of the
128
- track. This offset statically shifts the entire track (in centimeters) against the set of VR wall cues used during
129
- runtime. Storing this static offset as part of experiment configuration is crucial for correctly mapping what the
130
- animal sees during runtime to the real-world distance it travels on the running wheel."""
109
+ """Specifies the offset distance, in centimeters, by which the animal's running track is shifted relative to the
110
+ Virtual Reality (VR) environment's wall cue sequence. Due to how the VR environment is displayed to the animal,
111
+ most runtimes need to shift the animal slightly forward relative to the VR cue sequence origin (0), to prevent it
112
+ from seeing the portion of the environment before the first VR wall cue. This offset statically shifts the entire
113
+ track (in centimeters) against the set of VR wall cues used during runtime."""
131
114
  unity_scene_name: str = "IvanScene"
132
- """The name of the Virtual Reality task (Unity Scene) used during experiment. This is used as an extra security
133
- measure to ensure that Unity game engine is running the correct scene when starting the experiment runtime."""
115
+ """The name of the Virtual Reality task (Unity Scene) used during experiment."""
134
116
  experiment_states: dict[str, ExperimentState] = field(
135
117
  default_factory=lambda: {
136
118
  "baseline": ExperimentState(
@@ -159,8 +141,9 @@ class MesoscopeExperimentConfiguration(YamlConfig):
159
141
  ),
160
142
  }
161
143
  )
162
- """A dictionary that uses human-readable state-names as keys and ExperimentState instances as values. Each
163
- ExperimentState instance represents a phase of the experiment."""
144
+ """Maps human-readable experiment state names to corresponding ExperimentState instances. Each ExperimentState
145
+ instance represents a phase of the experiment. During runtime, the phases are executed in the same order as
146
+ specified in this dictionary."""
164
147
  trial_structures: dict[str, ExperimentTrial] = field(
165
148
  default_factory=lambda: {
166
149
  "cyclic_4_cue": ExperimentTrial(
@@ -173,54 +156,53 @@ class MesoscopeExperimentConfiguration(YamlConfig):
173
156
  )
174
157
  }
175
158
  )
176
- """A dictionary that uses human-readable trial structure names as keys and ExperimentTrial instances as values.
177
- Each ExperimentTrial instance specifies the Virtual Reality layout and runtime parameters associated with a single
159
+ """Maps human-readable trial structure names to corresponding ExperimentTrial instances. Each ExperimentTrial
160
+ instance specifies the Virtual Reality (VR) environment layout and task parameters associated with a single
178
161
  type of trials supported by the experiment runtime."""
179
162
 
180
163
 
181
164
  @dataclass()
182
165
  class MesoscopePaths:
183
- """Stores the filesystem configuration parameters for the Mesoscope-VR data acquisition system."""
166
+ """Stores the filesystem configuration parameters for the Mesoscope-VR data acquisition system.
167
+
168
+ Notes:
169
+ All directories specified in this instance must be mounted to the local PC's filesystem using an SMB or an
170
+ equivalent protocol.
171
+ """
184
172
 
185
173
  google_credentials_path: Path = Path("/media/Data/Experiments/sl-surgery-log-0f651e492767.json")
186
174
  """
187
- The path to the locally stored .JSON file that contains the service account credentials used to read and write
188
- Google Sheet data. This is used to access and work with various Google Sheet files used by Sun lab projects,
189
- eliminating the need to manually synchronize the data in various Google sheets and other data files.
175
+ The absolute path to the locally stored .JSON file that contains the service account credentials used to read and
176
+ write Google Sheet data. This is used to access and work with the Google Sheet files used in the Sun lab.
190
177
  """
191
178
  root_directory: Path = Path("/media/Data/Experiments")
192
- """The absolute path to the directory where all projects are stored on the local host-machine (VRPC)."""
179
+ """The absolute path to the directory where all projects are stored on the main data acquisition system PC."""
193
180
  server_storage_directory: Path = Path("/home/cybermouse/server/storage/sun_data")
194
- """The absolute path to the directory where the raw data from all projects is stored on the BioHPC server.
195
- This directory should be locally accessible (mounted) using a network sharing protocol, such as SMB."""
181
+ """The absolute path to the local-filesystem-mounted directory where the raw data from all projects is stored on
182
+ the remote compute server."""
196
183
  server_working_directory: Path = Path("/home/cybermouse/server/workdir/sun_data")
197
- """The absolute path to the directory where the processed data from all projects is stored on the BioHPC
198
- server. This directory should be locally accessible (mounted) using a network sharing protocol, such as SMB."""
184
+ """The absolute path to the local-filesystem-mounted directory where the processed data from all projects is
185
+ stored on the remote compute server."""
199
186
  nas_directory: Path = Path("/home/cybermouse/nas/rawdata")
200
- """The absolute path to the directory where the raw data from all projects is stored on the Synology NAS.
201
- This directory should be locally accessible (mounted) using a network sharing protocol, such as SMB."""
187
+ """The absolute path to the local-filesystem-mounted directory where the raw data from all projects is stored on
188
+ the NAS (backup long-term storage destination)."""
202
189
  mesoscope_directory: Path = Path("/home/cybermouse/scanimage/mesodata")
203
- """The absolute path to the root ScanImagePC (mesoscope-connected PC) directory where all mesoscope-acquired data
204
- is aggregated during acquisition runtime. This directory should be locally accessible (mounted) using a network
205
- sharing protocol, such as SMB."""
190
+ """The absolute path to the root ScanImagePC (mesoscope-connected PC) local-filesystem-mounted directory where all
191
+ mesoscope-acquired data is aggregated during acquisition."""
206
192
  harvesters_cti_path: Path = Path("/opt/mvIMPACT_Acquire/lib/x86_64/mvGenTLProducer.cti")
207
193
  """The path to the GeniCam CTI file used to connect to Harvesters-managed cameras."""
208
194
 
209
195
 
210
196
  @dataclass()
211
197
  class MesoscopeSheets:
212
- """Stores the IDs of Google Sheets used by the Mesoscope-VR data acquisition system."""
198
+ """Stores the identifiers for the Google Sheet files used by the Mesoscope-VR data acquisition system."""
213
199
 
214
200
  surgery_sheet_id: str = ""
215
- """The ID of the Google Sheet file that stores information about surgical interventions performed on all animals
216
- participating in each lab project. This log sheet is used to parse and write the surgical intervention data for
217
- each animal into every runtime session raw_data folder, so that the surgery data is always kept together with the
218
- rest of the training and experiment data."""
201
+ """The ID of the Google Sheet file that stores information about surgical interventions performed on the animals
202
+ that participate in data acquisition sessions."""
219
203
  water_log_sheet_id: str = ""
220
- """The ID of the Google Sheet file that stores information about water restriction (and behavior tracker)
221
- information for all animals participating in the managed project. This is used to synchronize the information
222
- inside the water restriction log with the state of the animal at the end of each training or experiment session.
223
- """
204
+ """The ID of the Google Sheet file that stores information about water restriction and user-interaction for all
205
+ animals that participate in data acquisition sessions."""
224
206
 
225
207
 
226
208
  @dataclass()
@@ -236,12 +218,9 @@ class MesoscopeCameras:
236
218
  """The index of the right body camera (from animal's perspective) in the list of all available OpenCV-managed
237
219
  cameras."""
238
220
  face_camera_quantization_parameter: int = 15
239
- """The quantization parameter used by the face camera to encode acquired frames as video files. This controls how
240
- much data is discarded when encoding each video frame, directly contributing to the encoding speed, resultant video
241
- file size and video quality."""
221
+ """The quantization parameter used by the face camera to encode acquired frames as video files."""
242
222
  body_camera_quantization_parameter: int = 15
243
- """SThe quantization parameter used by the left and right body cameras to encode acquired frames as video files.
244
- See 'face_camera_quantization_parameter' field for more information on what this parameter does."""
223
+ """The quantization parameter used by the left and right body cameras to encode acquired frames as video files."""
245
224
  display_face_camera_frames: bool = True
246
225
  """Determines whether to display the frames grabbed from the face camera during runtime."""
247
226
  display_body_camera_frames: bool = True
@@ -259,55 +238,50 @@ class MesoscopeMicroControllers:
259
238
  encoder_port: str = "/dev/ttyACM2"
260
239
  """The USB port used by the Encoder Microcontroller."""
261
240
  debug: bool = False
262
- """Determines whether to run the managed acquisition system in the 'debug mode'. This mode should be disabled
263
- during most runtimes. It is used during initial system calibration and testing and prints a lot of generally
264
- redundant information into the terminal."""
241
+ """Determines whether the acquisition system is running in the 'debug mode'. This mode is used during the initial
242
+ system calibration and testing. It should be disabled during all non-testing sessions to maximize system's
243
+ runtime performance."""
265
244
  minimum_break_strength_g_cm: float = 43.2047
266
245
  """The minimum torque applied by the running wheel break in gram centimeter. This is the torque the break delivers
267
- at minimum voltage (break is disabled)."""
246
+ at minimum operational voltage."""
268
247
  maximum_break_strength_g_cm: float = 1152.1246
269
248
  """The maximum torque applied by the running wheel break in gram centimeter. This is the torque the break delivers
270
- at maximum voltage (break is fully engaged)."""
249
+ at maximum operational voltage."""
271
250
  wheel_diameter_cm: float = 15.0333
272
- """The diameter of the running wheel connected to the break and torque sensor, in centimeters."""
251
+ """The diameter of the running wheel, in centimeters."""
273
252
  lick_threshold_adc: int = 400
274
253
  """The threshold voltage, in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC), interpreted
275
- as the animal's tongue contacting the sensor. Note, 12-bit ADC only supports values between 0 and 4095, so setting
276
- the threshold above 4095 will result in no licks being reported to Unity."""
254
+ as the animal's tongue contacting the sensor."""
277
255
  lick_signal_threshold_adc: int = 300
278
256
  """The minimum voltage, in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC), reported to the
279
257
  PC as a non-zero value. Voltages below this level are interpreted as 'no-lick' noise and are always pulled to 0."""
280
258
  lick_delta_threshold_adc: int = 300
281
259
  """The minimum absolute difference in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC) for
282
- the change to be reported to the PC. This is used to prevent reporting repeated non-lick or lick readouts to the
283
- PC, conserving communication bandwidth."""
260
+ the change to be reported to the PC."""
284
261
  lick_averaging_pool_size: int = 1
285
262
  """The number of lick sensor readouts to average together to produce the final lick sensor readout value. Note,
286
263
  when using a Teensy controller, this number is multiplied by the built-in analog readout averaging (default is 4).
287
264
  """
288
265
  torque_baseline_voltage_adc: int = 2046
289
- """The voltage level, in raw analog units measured by 3.3v Analog-to-Digital-Converter (ADC) at 12-bit resolution
290
- after the AD620 amplifier, that corresponds to no (0) torque readout. Usually, for a 3.3v ADC, this would be
291
- around 2046 (the midpoint, ~1.65 V)."""
266
+ """The voltage level, in raw analog units measured by a 12-bit Analog-to-Digital-Converter (ADC) after the AD620
267
+ amplifier, that corresponds to no torque (0) readout."""
292
268
  torque_maximum_voltage_adc: int = 2750
293
- """The voltage level, in raw analog units measured by 3.3v Analog-to-Digital-Converter (ADC) at 12-bit resolution
294
- after the AD620 amplifier, that corresponds to the absolute maximum torque detectable by the sensor. At most,
295
- this value can be 4095 (~3.3 V)."""
269
+ """The voltage level, in raw analog units measured by a 12-bit Analog-to-Digital-Converter (ADC)
270
+ after the AD620 amplifier, that corresponds to the absolute maximum torque detectable by the sensor."""
296
271
  torque_sensor_capacity_g_cm: float = 720.0779
297
272
  """The maximum torque detectable by the sensor, in grams centimeter (g cm)."""
298
273
  torque_report_cw: bool = True
299
274
  """Determines whether the sensor should report torque in the Clockwise (CW) direction. This direction corresponds
300
- to the animal trying to move the wheel backward."""
275
+ to the animal trying to move forward on the wheel."""
301
276
  torque_report_ccw: bool = True
302
277
  """Determines whether the sensor should report torque in the Counter-Clockwise (CCW) direction. This direction
303
- corresponds to the animal trying to move the wheel forward."""
278
+ corresponds to the animal trying to move backward on the wheel."""
304
279
  torque_signal_threshold_adc: int = 100
305
280
  """The minimum voltage, in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC), reported to the
306
281
  PC as a non-zero value. Voltages below this level are interpreted as noise and are always pulled to 0."""
307
282
  torque_delta_threshold_adc: int = 70
308
283
  """The minimum absolute difference in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC) for
309
- the change to be reported to the PC. This is used to prevent reporting repeated static torque readouts to the
310
- PC, conserving communication bandwidth."""
284
+ the change to be reported to the PC."""
311
285
  torque_averaging_pool_size: int = 1
312
286
  """The number of torque sensor readouts to average together to produce the final torque sensor readout value. Note,
313
287
  when using a Teensy controller, this number is multiplied by the built-in analog readout averaging (default is 4).
@@ -323,7 +297,7 @@ class MesoscopeMicroControllers:
323
297
  moving forward on the wheel."""
324
298
  wheel_encoder_delta_threshold_pulse: int = 15
325
299
  """The minimum difference, in encoder pulse counts, between two encoder readouts for the change to be reported to
326
- the PC. This is used to prevent reporting idle readouts and filter out sub-threshold noise."""
300
+ the PC."""
327
301
  wheel_encoder_polling_delay_us: int = 500
328
302
  """The delay, in microseconds, between any two successive encoder state readouts."""
329
303
  cm_per_unity_unit: float = 10.0
@@ -370,22 +344,15 @@ class MesoscopeAdditionalFirmware:
370
344
 
371
345
  @dataclass()
372
346
  class MesoscopeSystemConfiguration(YamlConfig):
373
- """Stores the hardware and filesystem configuration parameters for the Mesoscope-VR data acquisition system used in
374
- the Sun lab.
347
+ """Stores the hardware and filesystem configuration parameters for the Mesoscope-VR data acquisition system.
375
348
 
376
349
  This class is specifically designed to encapsulate the configuration parameters for the Mesoscope-VR system. It
377
- expects the system to be configured according to the specifications available from the sl_experiment repository
378
- (https://github.com/Sun-Lab-NBB/sl-experiment) and should be used exclusively by the VRPC machine
350
+ expects the system to be configured according to the specifications outlined in the sl-experiment repository
351
+ (https://github.com/Sun-Lab-NBB/sl-experiment) and should be used exclusively on the VRPC machine
379
352
  (main Mesoscope-VR PC).
380
-
381
- Notes:
382
- Each SystemConfiguration class is uniquely tied to a specific hardware configuration used in the lab. This
383
- class will only work with the Mesoscope-VR system. Any other data acquisition and runtime management system in
384
- the lab should define its own SystemConfiguration class to specify its own hardware and filesystem configuration
385
- parameters.
386
353
  """
387
354
 
388
- name: str = "mesoscope-vr"
355
+ name: str = str(AcquisitionSystems.MESOSCOPE_VR)
389
356
  """Stores the descriptive name of the data acquisition system."""
390
357
  paths: MesoscopePaths = field(default_factory=MesoscopePaths)
391
358
  """Stores the filesystem configuration parameters for the Mesoscope-VR data acquisition system."""
@@ -435,11 +402,11 @@ class MesoscopeSystemConfiguration(YamlConfig):
435
402
  console.error(message=message, error=TypeError)
436
403
 
437
404
  def save(self, path: Path) -> None:
438
- """Saves class instance data to disk as a 'mesoscope_system_configuration.yaml' file.
405
+ """Saves class instance data to disk as a .yaml file.
439
406
 
440
407
  This method converts certain class variables to yaml-safe types (for example, Path objects -> strings) and
441
408
  saves class data to disk as a .yaml file. The method is intended to be used solely by the
442
- set_system_configuration_file() function and should not be called from any other context.
409
+ create_system_configuration_file() function and should not be called from any other context.
443
410
 
444
411
  Args:
445
412
  path: The path to the .yaml file to save the data to.