sl-shared-assets 3.0.0rc4__tar.gz → 3.0.0rc6__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 (45) hide show
  1. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/PKG-INFO +1 -1
  2. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/pyproject.toml +1 -1
  3. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/__init__.py +0 -4
  4. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/__init__.pyi +0 -4
  5. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/__init__.py +1 -3
  6. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/__init__.pyi +0 -4
  7. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/configuration_data.py +27 -9
  8. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/configuration_data.pyi +9 -1
  9. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/runtime_data.py +15 -20
  10. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/runtime_data.pyi +6 -6
  11. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/session_data.py +12 -122
  12. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/session_data.pyi +8 -65
  13. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/ascension_tools.py +5 -20
  14. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/ascension_tools.pyi +0 -1
  15. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/.gitignore +0 -0
  16. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/LICENSE +0 -0
  17. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/README.md +0 -0
  18. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/Makefile +0 -0
  19. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/make.bat +0 -0
  20. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/source/api.rst +0 -0
  21. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/source/conf.py +0 -0
  22. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/source/index.rst +0 -0
  23. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/docs/source/welcome.rst +0 -0
  24. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/envs/slsa_dev_lin.yml +0 -0
  25. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/envs/slsa_dev_lin_spec.txt +0 -0
  26. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/cli.py +0 -0
  27. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/cli.pyi +0 -0
  28. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/surgery_data.py +0 -0
  29. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/data_classes/surgery_data.pyi +0 -0
  30. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/py.typed +0 -0
  31. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/__init__.py +0 -0
  32. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/__init__.pyi +0 -0
  33. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/job.py +0 -0
  34. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/job.pyi +0 -0
  35. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/server.py +0 -0
  36. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/server/server.pyi +0 -0
  37. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/__init__.py +0 -0
  38. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/__init__.pyi +0 -0
  39. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/packaging_tools.py +0 -0
  40. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/packaging_tools.pyi +0 -0
  41. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/project_management_tools.py +0 -0
  42. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/project_management_tools.pyi +0 -0
  43. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/transfer_tools.py +0 -0
  44. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/src/sl_shared_assets/tools/transfer_tools.pyi +0 -0
  45. {sl_shared_assets-3.0.0rc4 → sl_shared_assets-3.0.0rc6}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sl-shared-assets
3
- Version: 3.0.0rc4
3
+ Version: 3.0.0rc6
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/
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
8
  # Project metdata section. Provides the genral ID information about the project.
9
9
  [project]
10
10
  name = "sl-shared-assets"
11
- version = "3.0.0rc4"
11
+ version = "3.0.0rc6"
12
12
  description = "Provides data acquisition and processing assets shared between Sun (NeuroAI) lab libraries."
13
13
  readme = "README.md"
14
14
  license = { file = "LICENSE" }
@@ -20,7 +20,6 @@ from .data_classes import (
20
20
  SessionData,
21
21
  SubjectData,
22
22
  SurgeryData,
23
- VersionData,
24
23
  InjectionData,
25
24
  ProcedureData,
26
25
  ProcessedData,
@@ -31,7 +30,6 @@ from .data_classes import (
31
30
  TrialCueSequence,
32
31
  ProcessingTracker,
33
32
  MesoscopePositions,
34
- ProjectConfiguration,
35
33
  RunTrainingDescriptor,
36
34
  LickTrainingDescriptor,
37
35
  MesoscopeHardwareState,
@@ -59,7 +57,6 @@ __all__ = [
59
57
  "ImplantData",
60
58
  "SessionData",
61
59
  "RawData",
62
- "VersionData",
63
60
  "ProcessedData",
64
61
  "SubjectData",
65
62
  "SurgeryData",
@@ -69,7 +66,6 @@ __all__ = [
69
66
  "ZaberPositions",
70
67
  "ExperimentState",
71
68
  "MesoscopePositions",
72
- "ProjectConfiguration",
73
69
  "MesoscopeHardwareState",
74
70
  "RunTrainingDescriptor",
75
71
  "LickTrainingDescriptor",
@@ -16,7 +16,6 @@ from .data_classes import (
16
16
  SessionData as SessionData,
17
17
  SubjectData as SubjectData,
18
18
  SurgeryData as SurgeryData,
19
- VersionData as VersionData,
20
19
  InjectionData as InjectionData,
21
20
  ProcedureData as ProcedureData,
22
21
  ProcessedData as ProcessedData,
@@ -27,7 +26,6 @@ from .data_classes import (
27
26
  TrialCueSequence as TrialCueSequence,
28
27
  ProcessingTracker as ProcessingTracker,
29
28
  MesoscopePositions as MesoscopePositions,
30
- ProjectConfiguration as ProjectConfiguration,
31
29
  RunTrainingDescriptor as RunTrainingDescriptor,
32
30
  LickTrainingDescriptor as LickTrainingDescriptor,
33
31
  MesoscopeHardwareState as MesoscopeHardwareState,
@@ -49,7 +47,6 @@ __all__ = [
49
47
  "ImplantData",
50
48
  "SessionData",
51
49
  "RawData",
52
- "VersionData",
53
50
  "ProcessedData",
54
51
  "SubjectData",
55
52
  "SurgeryData",
@@ -59,7 +56,6 @@ __all__ = [
59
56
  "ZaberPositions",
60
57
  "ExperimentState",
61
58
  "MesoscopePositions",
62
- "ProjectConfiguration",
63
59
  "MesoscopeHardwareState",
64
60
  "RunTrainingDescriptor",
65
61
  "LickTrainingDescriptor",
@@ -11,7 +11,7 @@ from .runtime_data import (
11
11
  MesoscopeHardwareState,
12
12
  MesoscopeExperimentDescriptor,
13
13
  )
14
- from .session_data import RawData, SessionData, VersionData, ProcessedData, ProcessingTracker, ProjectConfiguration
14
+ from .session_data import RawData, SessionData, ProcessedData, ProcessingTracker
15
15
  from .surgery_data import (
16
16
  DrugData,
17
17
  ImplantData,
@@ -38,7 +38,6 @@ __all__ = [
38
38
  "ImplantData",
39
39
  "SessionData",
40
40
  "RawData",
41
- "VersionData",
42
41
  "ProcessedData",
43
42
  "SubjectData",
44
43
  "SurgeryData",
@@ -47,7 +46,6 @@ __all__ = [
47
46
  "ZaberPositions",
48
47
  "ExperimentState",
49
48
  "MesoscopePositions",
50
- "ProjectConfiguration",
51
49
  "MesoscopeHardwareState",
52
50
  "RunTrainingDescriptor",
53
51
  "LickTrainingDescriptor",
@@ -9,10 +9,8 @@ from .runtime_data import (
9
9
  from .session_data import (
10
10
  RawData as RawData,
11
11
  SessionData as SessionData,
12
- VersionData as VersionData,
13
12
  ProcessedData as ProcessedData,
14
13
  ProcessingTracker as ProcessingTracker,
15
- ProjectConfiguration as ProjectConfiguration,
16
14
  )
17
15
  from .surgery_data import (
18
16
  DrugData as DrugData,
@@ -40,7 +38,6 @@ __all__ = [
40
38
  "ImplantData",
41
39
  "SessionData",
42
40
  "RawData",
43
- "VersionData",
44
41
  "ProcessedData",
45
42
  "SubjectData",
46
43
  "SurgeryData",
@@ -49,7 +46,6 @@ __all__ = [
49
46
  "ZaberPositions",
50
47
  "ExperimentState",
51
48
  "MesoscopePositions",
52
- "ProjectConfiguration",
53
49
  "MesoscopeHardwareState",
54
50
  "RunTrainingDescriptor",
55
51
  "LickTrainingDescriptor",
@@ -66,7 +66,7 @@ class TrialCueSequence:
66
66
  during behavior data parsing to assign trial information to data collected from various sources.
67
67
  """
68
68
 
69
- cue_sequence: tuple[int, ...]
69
+ cue_sequence: list[int]
70
70
  """Specifies the sequence of wall cues experienced by the animal while running this trial."""
71
71
  trial_length_unity_unit: float
72
72
  """The length of the trial cue sequence, in Unity units."""
@@ -131,7 +131,7 @@ class MesoscopeExperimentConfiguration(YamlConfig):
131
131
  trial_structures: dict[str, TrialCueSequence] = field(
132
132
  default_factory=lambda: {
133
133
  "circular 4 cue": TrialCueSequence(
134
- cue_sequence=(0, 1, 0, 2, 0, 3, 0, 4), trial_length_unity_unit=24.0, trial_length_cm=240.0
134
+ cue_sequence=[0, 1, 0, 2, 0, 3, 0, 4], trial_length_unity_unit=24.0, trial_length_cm=240.0
135
135
  )
136
136
  }
137
137
  )
@@ -176,6 +176,22 @@ class MesoscopePaths:
176
176
  """The path to the GeniCam CTI file used to connect to Harvesters-managed cameras."""
177
177
 
178
178
 
179
+ @dataclass()
180
+ class MesoscopeSheets:
181
+ """Stores the IDs of Google Sheets used by the Mesoscope-VR data acquisition system."""
182
+
183
+ surgery_sheet_id: str = ""
184
+ """The ID of the Google Sheet file that stores information about surgical interventions performed on all animals
185
+ participating in each lab project. This log sheet is used to parse and write the surgical intervention data for
186
+ each animal into every runtime session raw_data folder, so that the surgery data is always kept together with the
187
+ rest of the training and experiment data."""
188
+ water_log_sheet_id: str = ""
189
+ """The ID of the Google Sheet file that stores information about water restriction (and behavior tracker)
190
+ information for all animals participating in the managed project. This is used to synchronize the information
191
+ inside the water restriction log with the state of the animal at the end of each training or experiment session.
192
+ """
193
+
194
+
179
195
  @dataclass()
180
196
  class MesoscopeCameras:
181
197
  """Stores the configuration parameters for the cameras used by the Mesoscope-VR system to record behavior videos."""
@@ -226,7 +242,7 @@ class MesoscopeMicroControllers:
226
242
  at maximum voltage (break is fully engaged)."""
227
243
  wheel_diameter_cm: float = 15.0333
228
244
  """The diameter of the running wheel connected to the break and torque sensor, in centimeters."""
229
- lick_threshold_adc: int = 500
245
+ lick_threshold_adc: int = 850
230
246
  """The threshold voltage, in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC), interpreted
231
247
  as the animal's tongue contacting the sensor. Note, 12-bit ADC only supports values between 0 and 4095, so setting
232
248
  the threshold above 4095 will result in no licks being reported to Unity."""
@@ -255,10 +271,10 @@ class MesoscopeMicroControllers:
255
271
  torque_report_ccw: bool = True
256
272
  """Determines whether the sensor should report torque in the Counter-Clockwise (CCW) direction. This direction
257
273
  corresponds to the animal trying to move the wheel forward."""
258
- torque_signal_threshold_adc: int = 300
274
+ torque_signal_threshold_adc: int = 100
259
275
  """The minimum voltage, in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC), reported to the
260
276
  PC as a non-zero value. Voltages below this level are interpreted as noise and are always pulled to 0."""
261
- torque_delta_threshold_adc: int = 300
277
+ torque_delta_threshold_adc: int = 70
262
278
  """The minimum absolute difference in raw analog units recorded by a 12-bit Analog-to-Digital-Converter (ADC) for
263
279
  the change to be reported to the PC. This is used to prevent reporting repeated static torque readouts to the
264
280
  PC, conserving communication bandwidth."""
@@ -293,10 +309,10 @@ class MesoscopeMicroControllers:
293
309
  encoder uses a dedicated parameter, as the encoder needs to be sampled at a higher frequency than all other sensors.
294
310
  """
295
311
  valve_calibration_data: dict[int | float, int | float] | tuple[tuple[int | float, int | float], ...] = (
296
- (15000, 1.75),
297
- (30000, 3.85),
298
- (45000, 7.95),
299
- (60000, 12.65),
312
+ (15000, 1.10),
313
+ (30000, 3.00),
314
+ (45000, 6.25),
315
+ (60000, 10.90),
300
316
  )
301
317
  """A tuple of tuples that maps water delivery solenoid valve open times, in microseconds, to the dispensed volume
302
318
  of water, in microliters. During training and experiment runtimes, this data is used by the ValveModule to translate
@@ -341,6 +357,8 @@ class MesoscopeSystemConfiguration(YamlConfig):
341
357
  """Stores the descriptive name of the data acquisition system."""
342
358
  paths: MesoscopePaths = field(default_factory=MesoscopePaths)
343
359
  """Stores the filesystem configuration parameters for the Mesoscope-VR data acquisition system."""
360
+ sheets: MesoscopeSheets = field(default_factory=MesoscopeSheets)
361
+ """Stores the IDs of Google Sheets used by the Mesoscope-VR data acquisition system."""
344
362
  cameras: MesoscopeCameras = field(default_factory=MesoscopeCameras)
345
363
  """Stores the configuration parameters for the cameras used by the Mesoscope-VR system to record behavior videos."""
346
364
  microcontrollers: MesoscopeMicroControllers = field(default_factory=MesoscopeMicroControllers)
@@ -38,7 +38,7 @@ class TrialCueSequence:
38
38
  during behavior data parsing to assign trial information to data collected from various sources.
39
39
  """
40
40
 
41
- cue_sequence: tuple[int, ...]
41
+ cue_sequence: list[int]
42
42
  trial_length_unity_unit: float
43
43
  trial_length_cm: float
44
44
 
@@ -78,6 +78,13 @@ class MesoscopePaths:
78
78
  mesoscope_directory: Path = ...
79
79
  harvesters_cti_path: Path = ...
80
80
 
81
+ @dataclass()
82
+ class MesoscopeSheets:
83
+ """Stores the IDs of Google Sheets used by the Mesoscope-VR data acquisition system."""
84
+
85
+ surgery_sheet_id: str = ...
86
+ water_log_sheet_id: str = ...
87
+
81
88
  @dataclass()
82
89
  class MesoscopeCameras:
83
90
  """Stores the configuration parameters for the cameras used by the Mesoscope-VR system to record behavior videos."""
@@ -155,6 +162,7 @@ class MesoscopeSystemConfiguration(YamlConfig):
155
162
 
156
163
  name: str = ...
157
164
  paths: MesoscopePaths = field(default_factory=MesoscopePaths)
165
+ sheets: MesoscopeSheets = field(default_factory=MesoscopeSheets)
158
166
  cameras: MesoscopeCameras = field(default_factory=MesoscopeCameras)
159
167
  microcontrollers: MesoscopeMicroControllers = field(default_factory=MesoscopeMicroControllers)
160
168
  additional_firmware: MesoscopeAdditionalFirmware = field(default_factory=MesoscopeAdditionalFirmware)
@@ -4,7 +4,7 @@ restore the data acquisition and runtime management system to the same state acr
4
4
  the same animal.
5
5
  """
6
6
 
7
- from dataclasses import field, dataclass
7
+ from dataclasses import dataclass
8
8
 
9
9
  from ataraxis_data_structures import YamlConfig
10
10
 
@@ -76,6 +76,9 @@ class MesoscopeHardwareState(YamlConfig):
76
76
  recorded_mesoscope_ttl: bool | None = None
77
77
  """TTLInterface instance property. A boolean flag that determines whether the processed session recorded brain
78
78
  activity data with the mesoscope."""
79
+ system_state_codes: dict[str, int] | None = None
80
+ """A MesoscopeVRSystem property. A dictionary that maps integer state-codes used by the Mesoscope-VR system to
81
+ communicate its states to human-readable state names."""
79
82
 
80
83
 
81
84
  @dataclass()
@@ -87,7 +90,8 @@ class LickTrainingDescriptor(YamlConfig):
87
90
  mouse_weight_g: float
88
91
  """The weight of the animal, in grams, at the beginning of the session."""
89
92
  dispensed_water_volume_ml: float
90
- """Stores the total water volume, in milliliters, dispensed during runtime."""
93
+ """Stores the total water volume, in milliliters, dispensed during runtime. This excludes the water volume
94
+ dispensed during the paused (idle) state."""
91
95
  minimum_reward_delay_s: int
92
96
  """Stores the minimum delay, in seconds, that can separate the delivery of two consecutive water rewards."""
93
97
  maximum_reward_delay_s: int
@@ -100,11 +104,8 @@ class LickTrainingDescriptor(YamlConfig):
100
104
  """Stores the maximum number of consecutive rewards that can be delivered without the animal consuming them. If
101
105
  the animal receives this many rewards without licking (consuming) them, reward delivery is paused until the animal
102
106
  consumes the rewards."""
103
- system_state_codes: dict[str, int] = field(
104
- default_factory=lambda: {"idle": 0, "rest": 1, "run": 2, "lick training": 3, "run training": 4}
105
- )
106
- """Maps integer state-codes used by the acquisition system to communicate its states to human-readable state
107
- names."""
107
+ pause_dispensed_water_volume_ml: float = 0.0
108
+ """Stores the total water volume, in milliliters, dispensed during the paused (idle) state."""
108
109
  experimenter_notes: str = "Replace this with your notes."
109
110
  """This field is not set during runtime. It is expected that each experimenter replaces this field with their
110
111
  notes made during runtime."""
@@ -155,11 +156,8 @@ class RunTrainingDescriptor(YamlConfig):
155
156
  """Stores the maximum time, in seconds, the animal can dip below the running speed threshold to still receive the
156
157
  reward. This allows animals that 'run' by taking a series of large steps, briefly dipping below speed threshold at
157
158
  the end of each step, to still get water rewards."""
158
- system_state_codes: dict[str, int] = field(
159
- default_factory=lambda: {"idle": 0, "rest": 1, "run": 2, "lick training": 3, "run training": 4}
160
- )
161
- """Maps integer state-codes used by the acquisition system to communicate its states to human-readable state
162
- names."""
159
+ pause_dispensed_water_volume_ml: float = 0.0
160
+ """Stores the total water volume, in milliliters, dispensed during the paused (idle) state."""
163
161
  experimenter_notes: str = "Replace this with your notes."
164
162
  """This field is not set during runtime. It is expected that each experimenter will replace this field with their
165
163
  notes made during runtime."""
@@ -185,14 +183,11 @@ class MesoscopeExperimentDescriptor(YamlConfig):
185
183
  """Stores the maximum number of consecutive rewards that can be delivered without the animal consuming them. If
186
184
  the animal receives this many rewards without licking (consuming) them, reward delivery is paused until the animal
187
185
  consumes the rewards."""
188
- system_state_codes: dict[str, int] = field(
189
- default_factory=lambda: {"idle": 0, "rest": 1, "run": 2, "lick training": 3, "run training": 4}
190
- )
191
- """Maps integer state-codes used by the acquisition system to communicate its states to human-readable state
192
- names."""
193
186
  experimenter_notes: str = "Replace this with your notes."
194
187
  """This field is not set during runtime. It is expected that each experimenter will replace this field with their
195
188
  notes made during runtime."""
189
+ pause_dispensed_water_volume_ml: float = 0.0
190
+ """Stores the total water volume, in milliliters, dispensed during the paused (idle) state."""
196
191
  experimenter_given_water_volume_ml: float = 0.0
197
192
  """The additional volume of water, in milliliters, administered by the experimenter to the animal after the session.
198
193
  """
@@ -229,15 +224,15 @@ class ZaberPositions(YamlConfig):
229
224
  """The absolute position, in native motor units, of the HeadBar pitch-axis motor."""
230
225
  headbar_roll: int = 0
231
226
  """The absolute position, in native motor units, of the HeadBar roll-axis motor."""
232
- wheel_x: int = 0
233
- """The absolute position, in native motor units, of the running wheel platform x-axis motor. Although this motor is
234
- not itself part of the HeadBar assembly, it is controlled through the HeadBar controller port."""
235
227
  lickport_z: int = 0
236
228
  """The absolute position, in native motor units, of the LickPort z-axis motor."""
237
229
  lickport_x: int = 0
238
230
  """The absolute position, in native motor units, of the LickPort x-axis motor."""
239
231
  lickport_y: int = 0
240
232
  """The absolute position, in native motor units, of the LickPort y-axis motor."""
233
+ wheel_x: int = 0
234
+ """The absolute position, in native motor units, of the running wheel platform x-axis motor. Although this motor is
235
+ not itself part of the HeadBar assembly, it is controlled through the HeadBar controller port."""
241
236
 
242
237
 
243
238
  @dataclass()
@@ -1,6 +1,5 @@
1
- from dataclasses import field, dataclass
1
+ from dataclasses import dataclass
2
2
 
3
- from _typeshed import Incomplete
4
3
  from ataraxis_data_structures import YamlConfig
5
4
 
6
5
  @dataclass()
@@ -43,6 +42,7 @@ class MesoscopeHardwareState(YamlConfig):
43
42
  torque_per_adc_unit: float | None = ...
44
43
  screens_initially_on: bool | None = ...
45
44
  recorded_mesoscope_ttl: bool | None = ...
45
+ system_state_codes: dict[str, int] | None = ...
46
46
 
47
47
  @dataclass()
48
48
  class LickTrainingDescriptor(YamlConfig):
@@ -56,7 +56,7 @@ class LickTrainingDescriptor(YamlConfig):
56
56
  maximum_water_volume_ml: float
57
57
  maximum_training_time_m: int
58
58
  maximum_unconsumed_rewards: int = ...
59
- system_state_codes: dict[str, int] = field(default_factory=Incomplete)
59
+ pause_dispensed_water_volume_ml: float = ...
60
60
  experimenter_notes: str = ...
61
61
  experimenter_given_water_volume_ml: float = ...
62
62
  incomplete: bool = ...
@@ -79,7 +79,7 @@ class RunTrainingDescriptor(YamlConfig):
79
79
  maximum_training_time_m: int
80
80
  maximum_unconsumed_rewards: int = ...
81
81
  maximum_idle_time_s: float = ...
82
- system_state_codes: dict[str, int] = field(default_factory=Incomplete)
82
+ pause_dispensed_water_volume_ml: float = ...
83
83
  experimenter_notes: str = ...
84
84
  experimenter_given_water_volume_ml: float = ...
85
85
  incomplete: bool = ...
@@ -92,8 +92,8 @@ class MesoscopeExperimentDescriptor(YamlConfig):
92
92
  mouse_weight_g: float
93
93
  dispensed_water_volume_ml: float
94
94
  maximum_unconsumed_rewards: int = ...
95
- system_state_codes: dict[str, int] = field(default_factory=Incomplete)
96
95
  experimenter_notes: str = ...
96
+ pause_dispensed_water_volume_ml: float = ...
97
97
  experimenter_given_water_volume_ml: float = ...
98
98
  incomplete: bool = ...
99
99
 
@@ -122,10 +122,10 @@ class ZaberPositions(YamlConfig):
122
122
  headbar_z: int = ...
123
123
  headbar_pitch: int = ...
124
124
  headbar_roll: int = ...
125
- wheel_x: int = ...
126
125
  lickport_z: int = ...
127
126
  lickport_x: int = ...
128
127
  lickport_y: int = ...
128
+ wheel_x: int = ...
129
129
 
130
130
  @dataclass()
131
131
  class MesoscopePositions(YamlConfig):
@@ -5,7 +5,6 @@ classes, which are also stored as .yaml files inside each session's raw_data and
5
5
  these classes contain all necessary information to restore the data hierarchy on any machine. All other Sun lab
6
6
  libraries use these classes to work with all lab-generated data."""
7
7
 
8
- import re
9
8
  import copy
10
9
  import shutil as sh
11
10
  from pathlib import Path
@@ -22,127 +21,6 @@ from .configuration_data import get_system_configuration_data
22
21
  _valid_session_types = {"lick training", "run training", "mesoscope experiment", "window checking"}
23
22
 
24
23
 
25
- @dataclass()
26
- class VersionData(YamlConfig):
27
- """Stores information about the versions of important Sun lab libraries used to acquire the session's data."""
28
-
29
- python_version: str = ""
30
- """Stores the Python version used by the environment that acquired the data."""
31
- sl_experiment_version: str = ""
32
- """Stores the version of the sl-experiment library that was used to acquire the data."""
33
-
34
-
35
- @dataclass()
36
- class ProjectConfiguration(YamlConfig):
37
- """Stores the project-specific configuration parameters that do not change between different animals and runtime
38
- sessions.
39
-
40
- An instance of this class is generated and saved as a .yaml file in the 'configuration' directory of each project
41
- when it is created. After that, the stored data is reused for every runtime (training or experiment session) carried
42
- out for each animal of the project. Additionally, a copy of the most actual configuration file is saved inside each
43
- runtime session's 'raw_data' folder, providing seamless integration between the managed data and various Sun lab
44
- (sl-) libraries.
45
-
46
- Notes:
47
- Together with SessionData, this class forms the entry point for all interactions with the data acquired in the
48
- Sun lab. The fields of this class are used to flexibly configure the runtime behavior of major data acquisition
49
- (sl-experiment) and processing (sl-forgery) libraries, adapting them for any project in the lab.
50
- """
51
-
52
- project_name: str = ""
53
- """Stores the descriptive name of the project. This name is used to create the root directory for the project and
54
- to initialize SessionData instances each time any Sun lab library interacts with the session's data."""
55
- surgery_sheet_id: str = ""
56
- """The ID of the Google Sheet file that stores information about surgical interventions performed on all animals
57
- participating in the managed project. This log sheet is used to parse and write the surgical intervention data for
58
- each animal into every runtime session raw_data folder, so that the surgery data is always kept together with the
59
- rest of the training and experiment data."""
60
- water_log_sheet_id: str = ""
61
- """The ID of the Google Sheet file that stores information about water restriction (and behavior tracker)
62
- information for all animals participating in the managed project. This is used to synchronize the information
63
- inside the water restriction log with the state of the animal at the end of each training or experiment session.
64
- """
65
-
66
- @classmethod
67
- def load(cls, configuration_path: Path) -> "ProjectConfiguration":
68
- """Loads the project configuration parameters from the specified project_configuration.yaml file.
69
-
70
- This method is called during each interaction with any runtime session's data, including the creation of a new
71
- session.
72
-
73
- Args:
74
- configuration_path: The path to the project_configuration.yaml file from which to load the data.
75
-
76
- Returns:
77
- The initialized ProjectConfiguration instance that stores the configuration data for the target project.
78
-
79
- Raise:
80
- FileNotFoundError: If the specified configuration file does not exist or is not a valid YAML file.
81
- """
82
-
83
- # Prevents loading non-existent files.
84
- if configuration_path.suffix != ".yaml" or not configuration_path.exists():
85
- message = (
86
- f"Unable to load the project configuration data from the specified path: {configuration_path}. Valid "
87
- f"configuration file paths should use the '.yaml' extension and point to an existing file."
88
- )
89
- console.error(message=message, error=FileNotFoundError)
90
-
91
- # Loads the data from the YAML file and initializes the class instance.
92
- instance: ProjectConfiguration = cls.from_yaml(file_path=configuration_path) # type: ignore
93
-
94
- # Verifies the loaded data. Most importantly, this step does not allow proceeding if the user did not
95
- # replace the surgery log and water restriction log placeholders with valid ID values.
96
- instance._verify_data()
97
-
98
- # Returns the initialized class instance to caller
99
- return instance
100
-
101
- def save(self, path: Path) -> None:
102
- """Saves class instance data to disk as a project_configuration.yaml file.
103
-
104
- This method is automatically called from the 'sl_experiment' library when a new project is created. After this
105
- method's runtime, all future project initialization calls will use the load() method to reuse configuration data
106
- saved to the .yaml file created by this method.
107
-
108
- Args:
109
- path: The path to the .yaml file to save the data to.
110
- """
111
-
112
- # Saves the data to the YAML file
113
- self.to_yaml(file_path=path)
114
-
115
- def _verify_data(self) -> None:
116
- """Verifies the user-modified data loaded from the project_configuration.yaml file.
117
-
118
- Since this class is explicitly designed to be modified by the user, this verification step is carried out to
119
- ensure that the loaded data matches expectations. This reduces the potential for user errors to impact the
120
- runtime behavior of the libraries using this class. This internal method is automatically called by the load()
121
- method.
122
-
123
- Raises:
124
- ValueError: If the loaded data does not match expected formats or values.
125
- """
126
-
127
- # Verifies Google Sheet ID formatting. Google Sheet IDs are usually 44 characters long, containing letters,
128
- # numbers, hyphens, and underscores
129
- pattern = r"^[a-zA-Z0-9_-]{44}$"
130
- if not re.match(pattern, self.surgery_sheet_id):
131
- message = (
132
- f"Unable to verify the surgery_sheet_id field loaded from the 'project_configuration.yaml' file. "
133
- f"Expected a string with 44 characters, using letters, numbers, hyphens, and underscores, but found: "
134
- f"{self.surgery_sheet_id}."
135
- )
136
- console.error(message=message, error=ValueError)
137
- if not re.match(pattern, self.water_log_sheet_id):
138
- message = (
139
- f"Unable to verify the surgery_sheet_id field loaded from the 'project_configuration.yaml' file. "
140
- f"Expected a string with 44 characters, using letters, numbers, hyphens, and underscores, but found: "
141
- f"{self.water_log_sheet_id}."
142
- )
143
- console.error(message=message, error=ValueError)
144
-
145
-
146
24
  @dataclass()
147
25
  class RawData:
148
26
  """Stores the paths to the directories and files that make up the 'raw_data' session-specific directory.
@@ -384,6 +262,10 @@ class SessionData(YamlConfig):
384
262
  field is not None (null), it communicates the specific experiment configuration used by the session. During runtime,
385
263
  the name stored here is used to load the specific experiment configuration data stored in a .yaml file with the
386
264
  same name. If the session is not an experiment session, this field is ignored."""
265
+ python_version: str = "3.11.13"
266
+ """Stores the Python version used to acquire raw session data."""
267
+ sl_experiment_version: str = "2.0.0"
268
+ """Stores the version of the sl-experiment library that was used to acquire the raw session data."""
387
269
  raw_data: RawData = field(default_factory=lambda: RawData())
388
270
  """Stores the paths to all subfolders and files found under the /project/animal/session/raw_data directory of any
389
271
  PC used to work with Sun lab data."""
@@ -407,6 +289,8 @@ class SessionData(YamlConfig):
407
289
  session_type: str,
408
290
  experiment_name: str | None = None,
409
291
  session_name: str | None = None,
292
+ python_version: str = "3.11.13",
293
+ sl_experiment_version: str = "2.0.0",
410
294
  ) -> "SessionData":
411
295
  """Creates a new SessionData object and generates the new session's data structure on the local PC.
412
296
 
@@ -433,6 +317,10 @@ class SessionData(YamlConfig):
433
317
  sessions. When provided, the method uses this name instead of generating a new timestamp-based name.
434
318
  This is only used during the 'ascension' runtime to convert old data structures to the modern
435
319
  lab standards.
320
+ python_version: The string that specifies the Python version used to collect raw session data. Has to be
321
+ specified using the major.minor.patch version format.
322
+ sl_experiment_version: The string that specifies the version of the sl-experiment library used to collect
323
+ raw session data. Has to be specified using the major.minor.patch version format.
436
324
 
437
325
  Returns:
438
326
  An initialized SessionData instance that stores the layout of the newly created session's data.
@@ -505,6 +393,8 @@ class SessionData(YamlConfig):
505
393
  raw_data=raw_data,
506
394
  processed_data=processed_data,
507
395
  experiment_name=experiment_name,
396
+ python_version=python_version,
397
+ sl_experiment_version=sl_experiment_version,
508
398
  )
509
399
 
510
400
  # Saves the configured instance data to the session's folder, so that it can be reused during processing or
@@ -8,71 +8,6 @@ from .configuration_data import get_system_configuration_data as get_system_conf
8
8
 
9
9
  _valid_session_types: Incomplete
10
10
 
11
- @dataclass()
12
- class VersionData(YamlConfig):
13
- """Stores information about the versions of important Sun lab libraries used to acquire the session's data."""
14
-
15
- python_version: str = ...
16
- sl_experiment_version: str = ...
17
-
18
- @dataclass()
19
- class ProjectConfiguration(YamlConfig):
20
- """Stores the project-specific configuration parameters that do not change between different animals and runtime
21
- sessions.
22
-
23
- An instance of this class is generated and saved as a .yaml file in the 'configuration' directory of each project
24
- when it is created. After that, the stored data is reused for every runtime (training or experiment session) carried
25
- out for each animal of the project. Additionally, a copy of the most actual configuration file is saved inside each
26
- runtime session's 'raw_data' folder, providing seamless integration between the managed data and various Sun lab
27
- (sl-) libraries.
28
-
29
- Notes:
30
- Together with SessionData, this class forms the entry point for all interactions with the data acquired in the
31
- Sun lab. The fields of this class are used to flexibly configure the runtime behavior of major data acquisition
32
- (sl-experiment) and processing (sl-forgery) libraries, adapting them for any project in the lab.
33
- """
34
-
35
- project_name: str = ...
36
- surgery_sheet_id: str = ...
37
- water_log_sheet_id: str = ...
38
- @classmethod
39
- def load(cls, configuration_path: Path) -> ProjectConfiguration:
40
- """Loads the project configuration parameters from the specified project_configuration.yaml file.
41
-
42
- This method is called during each interaction with any runtime session's data, including the creation of a new
43
- session.
44
-
45
- Args:
46
- configuration_path: The path to the project_configuration.yaml file from which to load the data.
47
-
48
- Returns:
49
- The initialized ProjectConfiguration instance that stores the configuration data for the target project.
50
-
51
- Raise:
52
- FileNotFoundError: If the specified configuration file does not exist or is not a valid YAML file.
53
- """
54
- def save(self, path: Path) -> None:
55
- """Saves class instance data to disk as a project_configuration.yaml file.
56
-
57
- This method is automatically called from the 'sl_experiment' library when a new project is created. After this
58
- method's runtime, all future project initialization calls will use the load() method to reuse configuration data
59
- saved to the .yaml file created by this method.
60
-
61
- Args:
62
- path: The path to the .yaml file to save the data to.
63
- """
64
- def _verify_data(self) -> None:
65
- """Verifies the user-modified data loaded from the project_configuration.yaml file.
66
-
67
- Since this class is explicitly designed to be modified by the user, this verification step is carried out to
68
- ensure that the loaded data matches expectations. This reduces the potential for user errors to impact the
69
- runtime behavior of the libraries using this class. This internal method is automatically called by the load()
70
- method.
71
-
72
- Raises:
73
- ValueError: If the loaded data does not match expected formats or values.
74
- """
75
-
76
11
  @dataclass()
77
12
  class RawData:
78
13
  """Stores the paths to the directories and files that make up the 'raw_data' session-specific directory.
@@ -178,6 +113,8 @@ class SessionData(YamlConfig):
178
113
  session_type: str
179
114
  acquisition_system: str
180
115
  experiment_name: str | None
116
+ python_version: str = ...
117
+ sl_experiment_version: str = ...
181
118
  raw_data: RawData = field(default_factory=Incomplete)
182
119
  processed_data: ProcessedData = field(default_factory=Incomplete)
183
120
  def __post_init__(self) -> None:
@@ -190,6 +127,8 @@ class SessionData(YamlConfig):
190
127
  session_type: str,
191
128
  experiment_name: str | None = None,
192
129
  session_name: str | None = None,
130
+ python_version: str = "3.11.13",
131
+ sl_experiment_version: str = "2.0.0",
193
132
  ) -> SessionData:
194
133
  """Creates a new SessionData object and generates the new session's data structure on the local PC.
195
134
 
@@ -216,6 +155,10 @@ class SessionData(YamlConfig):
216
155
  sessions. When provided, the method uses this name instead of generating a new timestamp-based name.
217
156
  This is only used during the 'ascension' runtime to convert old data structures to the modern
218
157
  lab standards.
158
+ python_version: The string that specifies the Python version used to collect raw session data. Has to be
159
+ specified using the major.minor.patch version format.
160
+ sl_experiment_version: The string that specifies the version of the sl-experiment library used to collect
161
+ raw session data. Has to be specified using the major.minor.patch version format.
219
162
 
220
163
  Returns:
221
164
  An initialized SessionData instance that stores the layout of the newly created session's data.
@@ -7,10 +7,10 @@ from pathlib import Path
7
7
  import datetime
8
8
 
9
9
  import numpy as np
10
- from ataraxis_base_utilities import LogLevel, console, ensure_directory_exists
10
+ from ataraxis_base_utilities import LogLevel, console
11
11
  from ataraxis_time.time_helpers import extract_timestamp_from_bytes
12
12
 
13
- from ..data_classes import SessionData, ProjectConfiguration, get_system_configuration_data
13
+ from ..data_classes import SessionData, get_system_configuration_data
14
14
  from .transfer_tools import transfer_directory
15
15
  from .packaging_tools import calculate_directory_checksum
16
16
 
@@ -194,26 +194,12 @@ def ascend_tyche_data(root_directory: Path) -> None:
194
194
  root_directory: The directory that stores one or more Tyche animal folders. This can be conceptualized as the
195
195
  root directory for the Tyche project.
196
196
  """
197
- # Generates a (shared) project configuration file.
198
- project_configuration = ProjectConfiguration()
199
-
200
197
  # The acquisition system config resolves most paths and filesystem configuration arguments
201
198
  acquisition_system = get_system_configuration_data()
202
- output_root_directory = acquisition_system.paths.root_directory
203
199
  server_root_directory = acquisition_system.paths.server_storage_directory
204
200
 
205
201
  # Statically defines project name and local root paths
206
202
  project_name = "Tyche"
207
- project_configuration.project_name = project_name
208
-
209
- # Uses nonsensical google sheet IDs. Tyche project did not use Google Sheet processing like our modern projects do.
210
- project_configuration.water_log_sheet_id = "1xFh9Q2zT7pL3mVkJdR8bN6yXoE4wS5aG0cHu2Kf7D3v"
211
- project_configuration.surgery_sheet_id = "1xFh9Q2zT7pL3mVkJdR8bN6yXoE4wS5aG0cHu2Kf7D3v"
212
-
213
- # Dumps project configuration into the 'configuration' subfolder of the Tyche project.
214
- configuration_path = output_root_directory.joinpath("Tyche", "configuration", "project_configuration.yaml")
215
- ensure_directory_exists(configuration_path)
216
- project_configuration.save(path=configuration_path)
217
203
 
218
204
  # Assumes that root directory stores all animal folders to be processed
219
205
  for animal_folder in root_directory.iterdir():
@@ -230,11 +216,10 @@ def ascend_tyche_data(root_directory: Path) -> None:
230
216
  # This procedure generates timestamp-based session names, analogous to how our modern pipeline does it.
231
217
  session_name = _generate_session_name(acquisition_path=acquisition_folder)
232
218
 
233
- # Uses derived session name and the statically created project configuration file to create the
234
- # session data hierarchy using the output root. This generates a 'standard' Sun lab directory structure
235
- # for the Tyche data.
219
+ # Uses derived session name and the derived project name to create the session data hierarchy using the
220
+ # output root. This generates a 'standard' Sun lab directory structure for the Tyche data.
236
221
  session_data = SessionData.create(
237
- project_name=project_configuration.project_name,
222
+ project_name=project_name,
238
223
  session_name=session_name,
239
224
  animal_id=animal_name,
240
225
  session_type="mesoscope experiment",
@@ -2,7 +2,6 @@ from pathlib import Path
2
2
 
3
3
  from ..data_classes import (
4
4
  SessionData as SessionData,
5
- ProjectConfiguration as ProjectConfiguration,
6
5
  get_system_configuration_data as get_system_configuration_data,
7
6
  )
8
7
  from .transfer_tools import transfer_directory as transfer_directory