sl-shared-assets 3.0.0rc10__py3-none-any.whl → 3.0.0rc12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sl-shared-assets might be problematic. Click here for more details.
- sl_shared_assets/__init__.py +6 -0
- sl_shared_assets/__init__.pyi +6 -0
- sl_shared_assets/data_classes/__init__.py +6 -1
- sl_shared_assets/data_classes/__init__.pyi +6 -0
- sl_shared_assets/data_classes/configuration_data.py +49 -39
- sl_shared_assets/data_classes/configuration_data.pyi +21 -15
- sl_shared_assets/data_classes/runtime_data.py +53 -41
- sl_shared_assets/data_classes/runtime_data.pyi +32 -26
- sl_shared_assets/data_classes/session_data.py +166 -124
- sl_shared_assets/data_classes/session_data.pyi +92 -57
- sl_shared_assets/data_classes/surgery_data.py +1 -1
- sl_shared_assets/tools/ascension_tools.py +2 -2
- sl_shared_assets/tools/ascension_tools.pyi +1 -0
- {sl_shared_assets-3.0.0rc10.dist-info → sl_shared_assets-3.0.0rc12.dist-info}/METADATA +2 -4
- {sl_shared_assets-3.0.0rc10.dist-info → sl_shared_assets-3.0.0rc12.dist-info}/RECORD +18 -18
- {sl_shared_assets-3.0.0rc10.dist-info → sl_shared_assets-3.0.0rc12.dist-info}/WHEEL +0 -0
- {sl_shared_assets-3.0.0rc10.dist-info → sl_shared_assets-3.0.0rc12.dist-info}/entry_points.txt +0 -0
- {sl_shared_assets-3.0.0rc10.dist-info → sl_shared_assets-3.0.0rc12.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,6 +6,7 @@ these classes contain all necessary information to restore the data hierarchy on
|
|
|
6
6
|
libraries use these classes to work with all lab-generated data."""
|
|
7
7
|
|
|
8
8
|
import copy
|
|
9
|
+
from enum import StrEnum
|
|
9
10
|
import shutil as sh
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from dataclasses import field, dataclass
|
|
@@ -15,18 +16,43 @@ from ataraxis_base_utilities import LogLevel, console, ensure_directory_exists
|
|
|
15
16
|
from ataraxis_data_structures import YamlConfig
|
|
16
17
|
from ataraxis_time.time_helpers import get_timestamp
|
|
17
18
|
|
|
18
|
-
from .configuration_data import get_system_configuration_data
|
|
19
|
+
from .configuration_data import AcquisitionSystems, get_system_configuration_data
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
class SessionTypes(StrEnum):
|
|
23
|
+
"""Defines the set of data acquisition session types supported by various data acquisition systems used in the
|
|
24
|
+
Sun lab.
|
|
25
|
+
|
|
26
|
+
A data acquisition session broadly encompasses a recording session carried out to either: acquire experiment data,
|
|
27
|
+
train the animal for the upcoming experiments, or to assess the quality of surgical or other pre-experiment
|
|
28
|
+
intervention.
|
|
29
|
+
|
|
30
|
+
Notes:
|
|
31
|
+
This enumeration does not differentiate between different acquisition systems. Different acquisition systems
|
|
32
|
+
support different session types, and may not be suited for acquiring some of the session types listed in this
|
|
33
|
+
enumeration.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
LICK_TRAINING = "lick training"
|
|
37
|
+
"""Mesoscope-VR session designed to teach animals to use the water delivery port while being head-fixed."""
|
|
38
|
+
RUN_TRAINING = "run training"
|
|
39
|
+
"""Mesoscope-VR session designed to teach animals how to run on the treadmill while being head-fixed."""
|
|
40
|
+
MESOSCOPE_EXPERIMENT = "mesoscope experiment"
|
|
41
|
+
"""Mesoscope-VR experiment session. The session uses Unity game engine to run experiments in virtual reality task
|
|
42
|
+
environments and collects brain activity data using Mesoscope."""
|
|
43
|
+
WINDOW_CHECKING = "window checking"
|
|
44
|
+
"""A special Mesoscope-VR session designed to evaluate the suitability of the given animal to be included into the
|
|
45
|
+
experiment dataset. Specifically, the session involves using the Mesoscope to check the quality of the cell
|
|
46
|
+
activity data."""
|
|
22
47
|
|
|
23
48
|
|
|
24
49
|
@dataclass()
|
|
25
50
|
class RawData:
|
|
26
51
|
"""Stores the paths to the directories and files that make up the 'raw_data' session-specific directory.
|
|
27
52
|
|
|
28
|
-
The raw_data directory stores the data acquired during the session runtime before and after
|
|
29
|
-
preprocessing does not alter the data, any data in that folder is considered
|
|
53
|
+
The raw_data directory stores the data acquired during the session data acquisition runtime, before and after
|
|
54
|
+
preprocessing. Since preprocessing does not irreversibly alter the data, any data in that folder is considered
|
|
55
|
+
'raw,' event if preprocessing losslessly re-compresses the data for efficient transfer.
|
|
30
56
|
|
|
31
57
|
Notes:
|
|
32
58
|
Sun lab data management strategy primarily relies on keeping multiple redundant copies of the raw_data for
|
|
@@ -43,35 +69,34 @@ class RawData:
|
|
|
43
69
|
includes .mp4 video files from each recorded camera."""
|
|
44
70
|
mesoscope_data_path: Path = Path()
|
|
45
71
|
"""Stores the path to the directory that contains all Mesoscope data acquired during the session. Primarily, this
|
|
46
|
-
includes the mesoscope-acquired .tiff files (brain activity data) and the
|
|
47
|
-
created for all sessions, but is only used (filled) by the sessions that use
|
|
48
|
-
brain activity data."""
|
|
72
|
+
includes the mesoscope-acquired .tiff files (brain activity data) and the MotionEstimator.me file (motion
|
|
73
|
+
estimation data). This directory is created for all sessions, but is only used (filled) by the sessions that use
|
|
74
|
+
the Mesoscope-VR system to acquire brain activity data."""
|
|
49
75
|
behavior_data_path: Path = Path()
|
|
50
76
|
"""Stores the path to the directory that contains all non-video behavior data acquired during the session.
|
|
51
77
|
Primarily, this includes the .npz log files that store serialized data acquired by all hardware components of the
|
|
52
|
-
data acquisition system other than cameras and brain activity data acquisition devices (such as the Mesoscope).
|
|
53
|
-
The reason why the directory is called 'behavior' is primarily because all .npz files are parsed to infer the
|
|
54
|
-
behavior of the animal, in contrast to brain (cell) activity data."""
|
|
78
|
+
data acquisition system other than cameras and brain activity data acquisition devices (such as the Mesoscope)."""
|
|
55
79
|
zaber_positions_path: Path = Path()
|
|
56
80
|
"""Stores the path to the zaber_positions.yaml file. This file contains the snapshot of all Zaber motor positions
|
|
57
|
-
at the end of the session. Zaber motors are used to position the LickPort
|
|
58
|
-
|
|
59
|
-
|
|
81
|
+
at the end of the session. Zaber motors are used to position the LickPort, HeadBar, and Wheel Mesoscope-VR modules
|
|
82
|
+
to support proper brain activity recording and behavior during the session. This file is only created for sessions
|
|
83
|
+
that use the Mesoscope-VR system."""
|
|
60
84
|
session_descriptor_path: Path = Path()
|
|
61
|
-
"""Stores the path to the session_descriptor.yaml file. This file is
|
|
62
|
-
and
|
|
63
|
-
|
|
85
|
+
"""Stores the path to the session_descriptor.yaml file. This file is filled jointly by the data acquisition system
|
|
86
|
+
and the experimenter. It contains session-specific information, such as the specific task parameters and the notes
|
|
87
|
+
made by the experimenter during runtime. Each supported session type uses a unique SessionDescriptor class to define
|
|
88
|
+
the format and content of the session_descriptor.yaml file."""
|
|
64
89
|
hardware_state_path: Path = Path()
|
|
65
90
|
"""Stores the path to the hardware_state.yaml file. This file contains the partial snapshot of the calibration
|
|
66
|
-
parameters used by the data acquisition
|
|
67
|
-
|
|
91
|
+
parameters used by the data acquisition system modules during the session. Primarily, it is used during data
|
|
92
|
+
processing to interpret the raw data stored inside .npz log files."""
|
|
68
93
|
surgery_metadata_path: Path = Path()
|
|
69
94
|
"""Stores the path to the surgery_metadata.yaml file. This file contains the most actual information about the
|
|
70
95
|
surgical intervention(s) performed on the animal prior to the session."""
|
|
71
96
|
session_data_path: Path = Path()
|
|
72
97
|
"""Stores the path to the session_data.yaml file. This path is used by the SessionData instance to save itself to
|
|
73
|
-
disk as a .yaml file.
|
|
74
|
-
|
|
98
|
+
disk as a .yaml file. In turn, the cached data is reused to reinstate the same data hierarchy across all supported
|
|
99
|
+
destinations, enabling various libraries to interface with the session data."""
|
|
75
100
|
experiment_configuration_path: Path = Path()
|
|
76
101
|
"""Stores the path to the experiment_configuration.yaml file. This file contains the snapshot of the
|
|
77
102
|
experiment runtime configuration used by the session. This file is only created for experiment sessions."""
|
|
@@ -81,13 +106,13 @@ class RawData:
|
|
|
81
106
|
the 'virtual' tip, tilt, and fastZ positions set via ScanImage software. This file is only created for sessions that
|
|
82
107
|
use the Mesoscope-VR system to acquire brain activity data."""
|
|
83
108
|
window_screenshot_path: Path = Path()
|
|
84
|
-
"""Stores the path to the .png screenshot of the ScanImagePC screen.
|
|
85
|
-
|
|
86
|
-
alignment and appearance for each experiment session. This file is only created for sessions
|
|
87
|
-
Mesoscope-VR system to acquire brain activity data."""
|
|
109
|
+
"""Stores the path to the .png screenshot of the ScanImagePC screen. As a minimum, the screenshot should contain the
|
|
110
|
+
image of the imaging plane and the red-dot alignment window. This is used to generate a visual snapshot of the
|
|
111
|
+
cranial window alignment and cell appearance for each experiment session. This file is only created for sessions
|
|
112
|
+
that use the Mesoscope-VR system to acquire brain activity data."""
|
|
88
113
|
system_configuration_path: Path = Path()
|
|
89
114
|
"""Stores the path to the system_configuration.yaml file. This file contains the exact snapshot of the data
|
|
90
|
-
acquisition
|
|
115
|
+
acquisition system configuration parameters used to acquire session data."""
|
|
91
116
|
checksum_path: Path = Path()
|
|
92
117
|
"""Stores the path to the ax_checksum.txt file. This file is generated as part of packaging the data for
|
|
93
118
|
transmission and stores the xxHash-128 checksum of the data. It is used to verify that the transmission did not
|
|
@@ -98,18 +123,16 @@ class RawData:
|
|
|
98
123
|
telomere.bin file are considered 'incomplete' and are excluded from all automated processing, as they may contain
|
|
99
124
|
corrupted, incomplete, or otherwise unusable data."""
|
|
100
125
|
ubiquitin_path: Path = Path()
|
|
101
|
-
"""Stores the path to the ubiquitin.bin file. This file is primarily used by the sl-experiment
|
|
126
|
+
"""Stores the path to the ubiquitin.bin file. This file is primarily used by the sl-experiment library to mark
|
|
102
127
|
local session data directories for deletion (purging). Typically, it is created once the data is safely moved to
|
|
103
128
|
the long-term storage destinations (NAS and Server) and the integrity of the moved data is verified on at least one
|
|
104
|
-
destination. During 'purge' sl-experiment runtimes, the library discovers and removes all session data marked
|
|
105
|
-
'ubiquitin.bin' files from the machine that runs the
|
|
129
|
+
destination. During 'sl-purge' sl-experiment runtimes, the library discovers and removes all session data marked
|
|
130
|
+
with 'ubiquitin.bin' files from the machine that runs the command."""
|
|
106
131
|
nk_path: Path = Path()
|
|
107
|
-
"""Stores the path to the nk.bin file. This file is used
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
initialize, marking that session's data for immediate deletion from all sources, as it does not contain any valid
|
|
112
|
-
information."""
|
|
132
|
+
"""Stores the path to the nk.bin file. This file is used by the sl-experiment library to mark sessions undergoing
|
|
133
|
+
runtime initialization. Since runtime initialization is a complex process that may encounter a runtime error, the
|
|
134
|
+
marker is used to discover sessions that failed to initialize. Since uninitialized sessions by definition do not
|
|
135
|
+
contain any valuable data, they are marked for immediate deletion from all managed destinations."""
|
|
113
136
|
integrity_verification_tracker_path: Path = Path()
|
|
114
137
|
"""Stores the path to the integrity_verification.yaml tracker file. This file stores the current state of the data
|
|
115
138
|
integrity verification pipeline. It prevents more than one instance of the pipeline from working with the data
|
|
@@ -118,13 +141,12 @@ class RawData:
|
|
|
118
141
|
def resolve_paths(self, root_directory_path: Path) -> None:
|
|
119
142
|
"""Resolves all paths managed by the class instance based on the input root directory path.
|
|
120
143
|
|
|
121
|
-
This method is called each time the class is instantiated to regenerate the managed path
|
|
122
|
-
machine that instantiates the class.
|
|
144
|
+
This method is called each time the (wrapper) SessionData class is instantiated to regenerate the managed path
|
|
145
|
+
hierarchy on any machine that instantiates the class.
|
|
123
146
|
|
|
124
147
|
Args:
|
|
125
|
-
root_directory_path: The path to the top-level directory of the
|
|
126
|
-
|
|
127
|
-
the managed session.
|
|
148
|
+
root_directory_path: The path to the top-level directory of the session. Typically, this path is assembled
|
|
149
|
+
using the following hierarchy: root/project/animal/session_id
|
|
128
150
|
"""
|
|
129
151
|
|
|
130
152
|
# Generates the managed paths
|
|
@@ -148,7 +170,11 @@ class RawData:
|
|
|
148
170
|
self.integrity_verification_tracker_path = self.raw_data_path.joinpath("integrity_verification_tracker.yaml")
|
|
149
171
|
|
|
150
172
|
def make_directories(self) -> None:
|
|
151
|
-
"""Ensures that all major subdirectories and the root directory exist, creating any missing directories.
|
|
173
|
+
"""Ensures that all major subdirectories and the root directory exist, creating any missing directories.
|
|
174
|
+
|
|
175
|
+
This method is called each time the (wrapper) SessionData class is instantiated and allowed to generate
|
|
176
|
+
missing data directories.
|
|
177
|
+
"""
|
|
152
178
|
ensure_directory_exists(self.raw_data_path)
|
|
153
179
|
ensure_directory_exists(self.camera_data_path)
|
|
154
180
|
ensure_directory_exists(self.mesoscope_data_path)
|
|
@@ -165,30 +191,30 @@ class ProcessedData:
|
|
|
165
191
|
"""
|
|
166
192
|
|
|
167
193
|
processed_data_path: Path = Path()
|
|
168
|
-
"""Stores the path to the root processed_data directory of the session. This directory stores the processed
|
|
169
|
-
|
|
194
|
+
"""Stores the path to the root processed_data directory of the session. This directory stores the processed session
|
|
195
|
+
data, generated from raw_data directory contents by various data processing pipelines."""
|
|
170
196
|
camera_data_path: Path = Path()
|
|
171
|
-
"""Stores the path to the directory that contains video tracking data generated by
|
|
172
|
-
processing
|
|
197
|
+
"""Stores the path to the directory that contains video tracking data generated by the Sun lab DeepLabCut-based
|
|
198
|
+
video processing pipeline(s)."""
|
|
173
199
|
mesoscope_data_path: Path = Path()
|
|
174
|
-
"""Stores path to the directory that contains processed brain activity (cell) data generated by
|
|
175
|
-
|
|
176
|
-
the Mesoscope-VR system.
|
|
200
|
+
"""Stores path to the directory that contains processed brain activity (cell) data generated by sl-suite2p
|
|
201
|
+
processing pipelines (single-day and multi-day). This directory is only used by sessions acquired with
|
|
202
|
+
the Mesoscope-VR system."""
|
|
177
203
|
behavior_data_path: Path = Path()
|
|
178
204
|
"""Stores the path to the directory that contains the non-video and non-brain-activity data extracted from
|
|
179
|
-
.npz log files by
|
|
205
|
+
.npz log files by the sl-behavior log processing pipeline."""
|
|
180
206
|
suite2p_processing_tracker_path: Path = Path()
|
|
181
|
-
"""Stores the path to the suite2p_processing_tracker.yaml tracker file. This file stores the current state of
|
|
182
|
-
sl-suite2p single-day
|
|
207
|
+
"""Stores the path to the suite2p_processing_tracker.yaml tracker file. This file stores the current state of
|
|
208
|
+
processing the session with the sl-suite2p single-day pipeline."""
|
|
183
209
|
behavior_processing_tracker_path: Path = Path()
|
|
184
|
-
"""Stores the path to the behavior_processing_tracker.yaml file. This file stores the current state of
|
|
185
|
-
behavior
|
|
210
|
+
"""Stores the path to the behavior_processing_tracker.yaml file. This file stores the current state of processing
|
|
211
|
+
the session with the sl-behavior log-parsing pipeline."""
|
|
186
212
|
video_processing_tracker_path: Path = Path()
|
|
187
|
-
"""Stores the path to the video_processing_tracker.yaml file. This file stores the current state of
|
|
188
|
-
|
|
213
|
+
"""Stores the path to the video_processing_tracker.yaml file. This file stores the current state of processing
|
|
214
|
+
the session with the DeepLabCut-based video processing pipeline."""
|
|
189
215
|
p53_path: Path = Path()
|
|
190
216
|
"""Stores the path to the p53.bin file. This file serves as a lock-in marker that determines whether the session is
|
|
191
|
-
in the processing or dataset
|
|
217
|
+
in the processing or dataset state. Specifically, if the file does not exist, the session data cannot be integrated
|
|
192
218
|
into any dataset, as it may be actively worked on by processing pipelines. Conversely, if the marker exists,
|
|
193
219
|
processing pipelines are not allowed to work with the session, as it may be actively integrated into one or more
|
|
194
220
|
datasets."""
|
|
@@ -196,13 +222,12 @@ class ProcessedData:
|
|
|
196
222
|
def resolve_paths(self, root_directory_path: Path) -> None:
|
|
197
223
|
"""Resolves all paths managed by the class instance based on the input root directory path.
|
|
198
224
|
|
|
199
|
-
This method is called each time the class is instantiated to regenerate the managed path
|
|
200
|
-
machine that instantiates the class.
|
|
225
|
+
This method is called each time the (wrapper) SessionData class is instantiated to regenerate the managed path
|
|
226
|
+
hierarchy on any machine that instantiates the class.
|
|
201
227
|
|
|
202
228
|
Args:
|
|
203
|
-
root_directory_path: The path to the top-level directory of the
|
|
204
|
-
|
|
205
|
-
the managed session.
|
|
229
|
+
root_directory_path: The path to the top-level directory of the session. Typically, this path is assembled
|
|
230
|
+
using the following hierarchy: root/project/animal/session_id
|
|
206
231
|
"""
|
|
207
232
|
# Generates the managed paths
|
|
208
233
|
self.processed_data_path = root_directory_path
|
|
@@ -215,7 +240,11 @@ class ProcessedData:
|
|
|
215
240
|
self.p53_path = self.processed_data_path.joinpath("p53.bin")
|
|
216
241
|
|
|
217
242
|
def make_directories(self) -> None:
|
|
218
|
-
"""Ensures that all major subdirectories and the root directory exist, creating any missing directories.
|
|
243
|
+
"""Ensures that all major subdirectories and the root directory exist, creating any missing directories.
|
|
244
|
+
|
|
245
|
+
This method is called each time the (wrapper) SessionData class is instantiated and allowed to generate
|
|
246
|
+
missing data directories.
|
|
247
|
+
"""
|
|
219
248
|
|
|
220
249
|
ensure_directory_exists(self.processed_data_path)
|
|
221
250
|
ensure_directory_exists(self.camera_data_path)
|
|
@@ -224,54 +253,51 @@ class ProcessedData:
|
|
|
224
253
|
|
|
225
254
|
@dataclass
|
|
226
255
|
class SessionData(YamlConfig):
|
|
227
|
-
"""Stores and manages the data layout of a single
|
|
228
|
-
|
|
229
|
-
The primary purpose of this class is to maintain the session data structure across all supported destinations and
|
|
230
|
-
during all processing stages. It generates the paths used by all other classes from all Sun lab libraries that
|
|
231
|
-
interact with the session's data from the point of its creation and until the data is integrated into an
|
|
232
|
-
analysis dataset.
|
|
256
|
+
"""Stores and manages the data layout of a single Sun lab data acquisition session.
|
|
233
257
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
session
|
|
258
|
+
The primary purpose of this class is to maintain the session data structure across all supported destinations and to
|
|
259
|
+
provide a unified data access interface shared by all Sun lab libraries. The class can be used to either generate a
|
|
260
|
+
new session or load the layout of an already existing session. When the class is used to create a new session, it
|
|
261
|
+
generates the new session's name using the current UTC timestamp, accurate to microseconds. This ensures that each
|
|
262
|
+
session 'name' is unique and preserves the overall session order.
|
|
238
263
|
|
|
239
264
|
Notes:
|
|
240
265
|
This class is specifically designed for working with the data from a single session, performed by a single
|
|
241
266
|
animal under the specific experiment. The class is used to manage both raw and processed data. It follows the
|
|
242
|
-
data through acquisition, preprocessing and processing stages of the Sun lab data workflow.
|
|
243
|
-
|
|
244
|
-
data.
|
|
267
|
+
data through acquisition, preprocessing and processing stages of the Sun lab data workflow. This class serves as
|
|
268
|
+
an entry point for all interactions with the managed session's data.
|
|
245
269
|
"""
|
|
246
270
|
|
|
247
271
|
project_name: str
|
|
248
|
-
"""Stores the name of the
|
|
272
|
+
"""Stores the name of the project for which the session was acquired."""
|
|
249
273
|
animal_id: str
|
|
250
|
-
"""Stores the unique identifier of the animal that participates in the
|
|
274
|
+
"""Stores the unique identifier of the animal that participates in the session."""
|
|
251
275
|
session_name: str
|
|
252
|
-
"""Stores the name (timestamp-based ID) of the
|
|
253
|
-
session_type: str
|
|
254
|
-
"""Stores the type of the session.
|
|
255
|
-
|
|
256
|
-
'mesoscope experiment'.
|
|
276
|
+
"""Stores the name (timestamp-based ID) of the session."""
|
|
277
|
+
session_type: str | SessionTypes
|
|
278
|
+
"""Stores the type of the session. Has to be set to one of the supported session types, defined in the SessionTypes
|
|
279
|
+
enumeration exposed by the sl-shared-assets library.
|
|
257
280
|
"""
|
|
258
|
-
acquisition_system: str
|
|
259
|
-
"""Stores the name of the data acquisition
|
|
281
|
+
acquisition_system: str | AcquisitionSystems
|
|
282
|
+
"""Stores the name of the data acquisition system that acquired the data. Has to be set to one of the supported
|
|
283
|
+
acquisition systems, defined in the AcquisitionSystems enumeration exposed by the sl-shared-assets library."""
|
|
260
284
|
experiment_name: str | None
|
|
261
|
-
"""Stores the name of the experiment
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
285
|
+
"""Stores the name of the experiment performed during the session. If the session_type field indicates that the
|
|
286
|
+
session is an experiment, this field communicates the specific experiment configuration used by the session. During
|
|
287
|
+
runtime, this name is used to load the specific experiment configuration data stored in a .yaml file with the same
|
|
288
|
+
name. If the session is not an experiment session, this field should be left as Null (None)."""
|
|
265
289
|
python_version: str = "3.11.13"
|
|
266
|
-
"""Stores the Python version used to acquire
|
|
290
|
+
"""Stores the Python version that was used to acquire session data."""
|
|
267
291
|
sl_experiment_version: str = "2.0.0"
|
|
268
|
-
"""Stores the version of the sl-experiment library that was used to acquire the
|
|
292
|
+
"""Stores the version of the sl-experiment library that was used to acquire the session data."""
|
|
269
293
|
raw_data: RawData = field(default_factory=lambda: RawData())
|
|
270
|
-
"""Stores
|
|
271
|
-
|
|
294
|
+
"""Stores absolute paths to all directories and files that jointly make the session's raw data hierarchy. This
|
|
295
|
+
directory structure is resolved for each machine that creates or loads the SessionData class to ensure that all
|
|
296
|
+
Sun lab data can be accessed via the same API on any destination."""
|
|
272
297
|
processed_data: ProcessedData = field(default_factory=lambda: ProcessedData())
|
|
273
|
-
"""Stores
|
|
274
|
-
|
|
298
|
+
"""Stores absolute paths to all directories and files that jointly make the session's processed data hierarchy.
|
|
299
|
+
Typically, this hierarchy is only used on the lab's processing server(s), but it can also be used to run local
|
|
300
|
+
testing on end-user machines."""
|
|
275
301
|
|
|
276
302
|
def __post_init__(self) -> None:
|
|
277
303
|
"""Ensures raw_data and processed_data are always instances of RawData and ProcessedData."""
|
|
@@ -286,7 +312,7 @@ class SessionData(YamlConfig):
|
|
|
286
312
|
cls,
|
|
287
313
|
project_name: str,
|
|
288
314
|
animal_id: str,
|
|
289
|
-
session_type: str,
|
|
315
|
+
session_type: SessionTypes | str,
|
|
290
316
|
experiment_name: str | None = None,
|
|
291
317
|
session_name: str | None = None,
|
|
292
318
|
python_version: str = "3.11.13",
|
|
@@ -301,35 +327,37 @@ class SessionData(YamlConfig):
|
|
|
301
327
|
To load an already existing session data structure, use the load() method instead.
|
|
302
328
|
|
|
303
329
|
This method automatically dumps the data of the created SessionData instance into the session_data.yaml file
|
|
304
|
-
inside the root raw_data directory of the created hierarchy. It also finds and dumps other configuration
|
|
305
|
-
files, such as experiment_configuration.yaml and system_configuration.yaml into the same raw_data
|
|
306
|
-
|
|
307
|
-
|
|
330
|
+
inside the root 'raw_data' directory of the created hierarchy. It also finds and dumps other configuration
|
|
331
|
+
files, such as experiment_configuration.yaml and system_configuration.yaml into the same 'raw_data'
|
|
332
|
+
directory. If the session's runtime is interrupted unexpectedly, the acquired data can still be processed
|
|
333
|
+
using these pre-saved class instances.
|
|
308
334
|
|
|
309
335
|
Args:
|
|
310
|
-
project_name: The name of the project for which the
|
|
311
|
-
animal_id: The ID code of the animal
|
|
312
|
-
session_type: The type of the session.
|
|
313
|
-
|
|
314
|
-
experiment_name: The name of the experiment executed during
|
|
315
|
-
used for
|
|
316
|
-
|
|
336
|
+
project_name: The name of the project for which the session is carried out.
|
|
337
|
+
animal_id: The ID code of the animal participating in the session.
|
|
338
|
+
session_type: The type of the session. Has to be one of the supported session types exposed by the
|
|
339
|
+
SessionTypes enumeration.
|
|
340
|
+
experiment_name: The name of the experiment executed during the session. This optional argument is only
|
|
341
|
+
used for experiment sessions. Note! The name passed to this argument has to match the name of the
|
|
342
|
+
experiment configuration .yaml file.
|
|
343
|
+
session_name: An optional session name override. Generally, this argument should not be provided for most
|
|
317
344
|
sessions. When provided, the method uses this name instead of generating a new timestamp-based name.
|
|
318
345
|
This is only used during the 'ascension' runtime to convert old data structures to the modern
|
|
319
346
|
lab standards.
|
|
320
|
-
python_version: The string that specifies the Python version used to collect
|
|
347
|
+
python_version: The string that specifies the Python version used to collect session data. Has to be
|
|
321
348
|
specified using the major.minor.patch version format.
|
|
322
349
|
sl_experiment_version: The string that specifies the version of the sl-experiment library used to collect
|
|
323
|
-
|
|
350
|
+
session data. Has to be specified using the major.minor.patch version format.
|
|
324
351
|
|
|
325
352
|
Returns:
|
|
326
353
|
An initialized SessionData instance that stores the layout of the newly created session's data.
|
|
327
354
|
"""
|
|
328
355
|
|
|
329
|
-
|
|
356
|
+
# Need to convert to tuple to support Python 3.11
|
|
357
|
+
if session_type not in tuple(SessionTypes):
|
|
330
358
|
message = (
|
|
331
|
-
f"Invalid session type '{session_type
|
|
332
|
-
f"Use one of the supported session types
|
|
359
|
+
f"Invalid session type '{session_type}' encountered when creating a new SessionData instance. "
|
|
360
|
+
f"Use one of the supported session types from the SessionTypes enumeration."
|
|
333
361
|
)
|
|
334
362
|
console.error(message=message, error=ValueError)
|
|
335
363
|
|
|
@@ -388,7 +416,7 @@ class SessionData(YamlConfig):
|
|
|
388
416
|
project_name=project_name,
|
|
389
417
|
animal_id=animal_id,
|
|
390
418
|
session_name=session_name,
|
|
391
|
-
session_type=session_type
|
|
419
|
+
session_type=session_type,
|
|
392
420
|
acquisition_system=acquisition_system.name,
|
|
393
421
|
raw_data=raw_data,
|
|
394
422
|
processed_data=processed_data,
|
|
@@ -432,9 +460,9 @@ class SessionData(YamlConfig):
|
|
|
432
460
|
"""Loads the SessionData instance from the target session's session_data.yaml file.
|
|
433
461
|
|
|
434
462
|
This method is used to load the data layout information of an already existing session. Primarily, this is used
|
|
435
|
-
when
|
|
436
|
-
|
|
437
|
-
|
|
463
|
+
when processing session data. Due to how SessionData is stored and used in the lab, this method always loads the
|
|
464
|
+
data layout from the session_data.yaml file stored inside the 'raw_data' session subfolder. Currently, all
|
|
465
|
+
interactions with Sun lab data require access to the 'raw_data' folder of each session.
|
|
438
466
|
|
|
439
467
|
Notes:
|
|
440
468
|
To create a new session, use the create() method instead.
|
|
@@ -501,16 +529,16 @@ class SessionData(YamlConfig):
|
|
|
501
529
|
def runtime_initialized(self) -> None:
|
|
502
530
|
"""Ensures that the 'nk.bin' marker file is removed from the session's raw_data folder.
|
|
503
531
|
|
|
504
|
-
|
|
505
|
-
not fully initialize during runtime. This service method is designed to be called by the
|
|
506
|
-
|
|
532
|
+
The 'nk.bin' marker is generated as part of the SessionData initialization (creation) process to mark sessions
|
|
533
|
+
that did not fully initialize during runtime. This service method is designed to be called by the sl-experiment
|
|
534
|
+
library classes to remove the 'nk.bin' marker when it is safe to do so. It should not be called by end-users.
|
|
507
535
|
"""
|
|
508
536
|
self.raw_data.nk_path.unlink(missing_ok=True)
|
|
509
537
|
|
|
510
538
|
def _save(self) -> None:
|
|
511
539
|
"""Saves the instance data to the 'raw_data' directory of the managed session as a 'session_data.yaml' file.
|
|
512
540
|
|
|
513
|
-
This is used to save the data stored in the instance to disk, so that it can be reused during
|
|
541
|
+
This is used to save the data stored in the instance to disk, so that it can be reused during further stages of
|
|
514
542
|
data processing. The method is intended to only be used by the SessionData instance itself during its
|
|
515
543
|
create() method runtime.
|
|
516
544
|
"""
|
|
@@ -561,6 +589,16 @@ class ProcessingTracker(YamlConfig):
|
|
|
561
589
|
else:
|
|
562
590
|
self._lock_path = ""
|
|
563
591
|
|
|
592
|
+
def __del__(self) -> None:
|
|
593
|
+
"""If the instance is garbage-collected without calling the stop() method, assumes this is due to a runtime
|
|
594
|
+
error.
|
|
595
|
+
|
|
596
|
+
It is essential to always resolve the runtime as either 'stopped' or 'erred' to avoid deadlocking the session
|
|
597
|
+
data.
|
|
598
|
+
"""
|
|
599
|
+
if self._is_running:
|
|
600
|
+
self.error()
|
|
601
|
+
|
|
564
602
|
def _load_state(self) -> None:
|
|
565
603
|
"""Reads the current processing state from the wrapped .YAML file."""
|
|
566
604
|
if self.file_path.exists():
|
|
@@ -671,7 +709,11 @@ class ProcessingTracker(YamlConfig):
|
|
|
671
709
|
raise Timeout(message) # Fallback to appease mypy, should not be reachable
|
|
672
710
|
|
|
673
711
|
def stop(self) -> None:
|
|
674
|
-
"""
|
|
712
|
+
"""Configures the tracker file to indicate that the tracked processing runtime has been completed successfully.
|
|
713
|
+
|
|
714
|
+
After this method returns, it is UNSAFE to do any further processing from the process that calls this method.
|
|
715
|
+
Any process that calls the 'start' method of this class is expected to also call this method or 'error' method
|
|
716
|
+
at the end of the runtime.
|
|
675
717
|
|
|
676
718
|
Raises:
|
|
677
719
|
TimeoutError: If the file lock for the target .YAML file cannot be acquired within the timeout period.
|
|
@@ -713,7 +755,7 @@ class ProcessingTracker(YamlConfig):
|
|
|
713
755
|
@property
|
|
714
756
|
def is_complete(self) -> bool:
|
|
715
757
|
"""Returns True if the tracker wrapped by the instance indicates that the processing runtime has been completed
|
|
716
|
-
successfully and
|
|
758
|
+
successfully at least once and that there is no ongoing processing that uses the target session."""
|
|
717
759
|
try:
|
|
718
760
|
# Acquires the lock
|
|
719
761
|
lock = FileLock(self._lock_path)
|
|
@@ -734,8 +776,8 @@ class ProcessingTracker(YamlConfig):
|
|
|
734
776
|
|
|
735
777
|
@property
|
|
736
778
|
def encountered_error(self) -> bool:
|
|
737
|
-
"""Returns True if the tracker wrapped by the instance indicates that the processing runtime
|
|
738
|
-
encountering an error
|
|
779
|
+
"""Returns True if the tracker wrapped by the instance indicates that the processing runtime for the target
|
|
780
|
+
session has aborted due to encountering an error."""
|
|
739
781
|
try:
|
|
740
782
|
# Acquires the lock
|
|
741
783
|
lock = FileLock(self._lock_path)
|
|
@@ -757,7 +799,7 @@ class ProcessingTracker(YamlConfig):
|
|
|
757
799
|
@property
|
|
758
800
|
def is_running(self) -> bool:
|
|
759
801
|
"""Returns True if the tracker wrapped by the instance indicates that the processing runtime is currently
|
|
760
|
-
running
|
|
802
|
+
running for the target session."""
|
|
761
803
|
try:
|
|
762
804
|
# Acquires the lock
|
|
763
805
|
lock = FileLock(self._lock_path)
|