sl-shared-assets 1.0.0rc8__py3-none-any.whl → 1.0.0rc10__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 +0 -36
- sl_shared_assets/ascension_tools.py +279 -0
- sl_shared_assets/cli.py +43 -3
- sl_shared_assets/data_classes.py +178 -144
- sl_shared_assets/packaging_tools.py +1 -0
- {sl_shared_assets-1.0.0rc8.dist-info → sl_shared_assets-1.0.0rc10.dist-info}/METADATA +1 -1
- sl_shared_assets-1.0.0rc10.dist-info/RECORD +14 -0
- {sl_shared_assets-1.0.0rc8.dist-info → sl_shared_assets-1.0.0rc10.dist-info}/entry_points.txt +1 -0
- sl_shared_assets/__init__.pyi +0 -87
- sl_shared_assets/cli.pyi +0 -17
- sl_shared_assets/data_classes.pyi +0 -667
- sl_shared_assets/packaging_tools.pyi +0 -52
- sl_shared_assets/server.pyi +0 -112
- sl_shared_assets/suite2p.pyi +0 -188
- sl_shared_assets/transfer_tools.pyi +0 -53
- sl_shared_assets-1.0.0rc8.dist-info/RECORD +0 -20
- {sl_shared_assets-1.0.0rc8.dist-info → sl_shared_assets-1.0.0rc10.dist-info}/WHEEL +0 -0
- {sl_shared_assets-1.0.0rc8.dist-info → sl_shared_assets-1.0.0rc10.dist-info}/licenses/LICENSE +0 -0
sl_shared_assets/data_classes.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"""This module provides classes used to store various data used by
|
|
2
|
-
This includes classes used to store the data generated during acquisition and preprocessing and classes used
|
|
3
|
-
the runtime of other libraries (configuration data classes).
|
|
1
|
+
"""This module provides classes used to store various data used by other Sun lab data acquisition and processing
|
|
2
|
+
libraries.This includes classes used to store the data generated during acquisition and preprocessing and classes used
|
|
3
|
+
to manage the runtime of other libraries (configuration data classes). Most classes from these modules are used by the
|
|
4
|
+
major libraries 'sl-experiment' and 'sl-forgery'."""
|
|
4
5
|
|
|
5
6
|
import re
|
|
6
7
|
import copy
|
|
@@ -13,17 +14,20 @@ import appdirs
|
|
|
13
14
|
from ataraxis_base_utilities import LogLevel, console, ensure_directory_exists
|
|
14
15
|
from ataraxis_data_structures import YamlConfig
|
|
15
16
|
from ataraxis_time.time_helpers import get_timestamp
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
# Ensures console is enabled when this file is imported
|
|
19
|
+
if not console.enabled:
|
|
20
|
+
console.enable()
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
def replace_root_path(path: Path) -> None:
|
|
20
24
|
"""Replaces the path to the local root directory used to store all Sun lab projects with the provided path.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
the path to the local directory where to save all Sun lab projects. This path is then
|
|
24
|
-
user data directory as a .yaml file to be reused for all future projects. To support
|
|
25
|
-
searching for the user data directory, which is usually hidden, this function finds and
|
|
26
|
-
file that stores the local root path.
|
|
26
|
+
The first time ProjectConfiguration class is instantiated to create a new project on a new machine,
|
|
27
|
+
it asks the user to provide the path to the local directory where to save all Sun lab projects. This path is then
|
|
28
|
+
stored inside the default user data directory as a .yaml file to be reused for all future projects. To support
|
|
29
|
+
replacing this path without searching for the user data directory, which is usually hidden, this function finds and
|
|
30
|
+
updates the contents of the file that stores the local root path.
|
|
27
31
|
|
|
28
32
|
Args:
|
|
29
33
|
path: The path to the new local root directory.
|
|
@@ -50,53 +54,65 @@ class ProjectConfiguration(YamlConfig):
|
|
|
50
54
|
|
|
51
55
|
An instance of this class is generated and saved as a .yaml file in the 'configuration' directory of each project
|
|
52
56
|
when it is created. After that, the stored data is reused for every runtime (training or experiment session) carried
|
|
53
|
-
out for each animal of the project.
|
|
57
|
+
out for each animal of the project. Additionally, a copy of the most actual configuration file is saved inside each
|
|
58
|
+
runtime session's 'raw_data' folder, providing seamless integration between the managed data and various Sun lab
|
|
59
|
+
(sl-) libraries.
|
|
54
60
|
|
|
55
61
|
Notes:
|
|
56
|
-
|
|
57
|
-
Sun lab.
|
|
58
|
-
|
|
62
|
+
Together with SessionData, this class forms the entry point for all interactions with the data acquired in the
|
|
63
|
+
Sun lab. The fields of this class are used to flexibly configure the runtime behavior of major data acquisition
|
|
64
|
+
(sl-experiment) and processing (sl-forgery) libraries, adapting them for any project in the lab.
|
|
65
|
+
|
|
66
|
+
Most lab projects only need to adjust the "surgery_sheet_id" and "water_log_sheet_id" fields of the class. Most
|
|
67
|
+
fields in this class are used by the sl-experiment library to generate the SessionData class instance for each
|
|
68
|
+
session and during experiment data acquisition and preprocessing. Data processing pipelines use specialized
|
|
69
|
+
configuration files stored in other modules of this library.
|
|
59
70
|
|
|
60
|
-
|
|
71
|
+
Although all path fields use str | Path datatype, they are always stored as Path objects. These fields are
|
|
72
|
+
converted to strings only when the data is dumped as a .yaml file.
|
|
61
73
|
"""
|
|
62
74
|
|
|
63
75
|
project_name: str = ""
|
|
64
76
|
"""Stores the descriptive name of the project. This name is used to create the root directory for the project and
|
|
65
77
|
to discover and load project's data during runtime."""
|
|
66
78
|
surgery_sheet_id: str = ""
|
|
67
|
-
"""The ID of the Google Sheet file that stores
|
|
68
|
-
|
|
69
|
-
that the surgery data is always kept together with the
|
|
79
|
+
"""The ID of the Google Sheet file that stores information about surgical interventions performed on all animals
|
|
80
|
+
participating in the managed project. This log sheet is used to parse and write the surgical intervention data for
|
|
81
|
+
each animal into every runtime session raw_data folder, so that the surgery data is always kept together with the
|
|
82
|
+
rest of the training and experiment data."""
|
|
70
83
|
water_log_sheet_id: str = ""
|
|
71
|
-
"""The ID of the Google Sheet file that stores
|
|
72
|
-
|
|
73
|
-
the animal at the end of each training or experiment session.
|
|
84
|
+
"""The ID of the Google Sheet file that stores information about water restriction (and behavior tracker)
|
|
85
|
+
information for all animals participating in the managed project. This is used to synchronize the information
|
|
86
|
+
inside the water restriction log with the state of the animal at the end of each training or experiment session.
|
|
74
87
|
"""
|
|
75
88
|
google_credentials_path: str | Path = Path("/media/Data/Experiments/sl-surgery-log-0f651e492767.json")
|
|
76
89
|
"""
|
|
77
90
|
The path to the locally stored .JSON file that contains the service account credentials used to read and write
|
|
78
|
-
Google Sheet data. This is used to access and work with the surgery log and the water restriction log.
|
|
79
|
-
same service account is used across all projects.
|
|
91
|
+
Google Sheet data. This is used to access and work with the surgery log and the water restriction log files.
|
|
92
|
+
Usually, the same service account is used across all projects.
|
|
80
93
|
"""
|
|
81
94
|
server_credentials_path: str | Path = Path("/media/Data/Experiments/server_credentials.yaml")
|
|
82
95
|
"""
|
|
83
96
|
The path to the locally stored .YAML file that contains the credentials for accessing the BioHPC server machine.
|
|
84
|
-
While the
|
|
85
|
-
is used to establish SSH connection to the
|
|
86
|
-
This
|
|
97
|
+
While the filesystem of the server machine should already be mounted to the local machine via SMB or equivalent
|
|
98
|
+
protocol, this data is used to establish SSH connection to the server and start newly acquired data processing
|
|
99
|
+
after it is transferred to the server. This allows data acquisition, preprocessing, and processing to be controlled
|
|
100
|
+
by the same runtime and prevents unprocessed data from piling up on the server.
|
|
87
101
|
"""
|
|
88
102
|
local_root_directory: str | Path = Path("/media/Data/Experiments")
|
|
89
|
-
"""The absolute path to the
|
|
90
|
-
|
|
103
|
+
"""The absolute path to the directory where all projects are stored on the local host-machine (VRPC). Note,
|
|
104
|
+
this field is configured automatically each time the class is instantiated through any method, so overwriting it
|
|
105
|
+
manually will not be respected."""
|
|
91
106
|
local_server_directory: str | Path = Path("/home/cybermouse/server/storage/sun_data")
|
|
92
|
-
"""The absolute path to the
|
|
93
|
-
|
|
107
|
+
"""The absolute path to the directory where all projects are stored on the BioHPC server. This directory should be
|
|
108
|
+
locally accessible (mounted) using a network sharing protocol, such as SMB."""
|
|
94
109
|
local_nas_directory: str | Path = Path("/home/cybermouse/nas/rawdata")
|
|
95
|
-
"""The absolute path to the
|
|
96
|
-
|
|
110
|
+
"""The absolute path to the directory where all projects are stored on the Synology NAS. This directory should be
|
|
111
|
+
locally accessible (mounted) using a network sharing protocol, such as SMB."""
|
|
97
112
|
local_mesoscope_directory: str | Path = Path("/home/cybermouse/scanimage/mesodata")
|
|
98
|
-
"""The absolute path to the
|
|
99
|
-
|
|
113
|
+
"""The absolute path to the root mesoscope (ScanImagePC) directory where all mesoscope-acquired data is aggregated
|
|
114
|
+
during acquisition runtime. This directory should be locally accessible (mounted) using a network sharing
|
|
115
|
+
protocol, such as SMB."""
|
|
100
116
|
remote_storage_directory: str | Path = Path("/storage/sun_data")
|
|
101
117
|
"""The absolute path, relative to the BioHPC server root, to the directory where all projects are stored on the
|
|
102
118
|
slow (SSD) volume of the server. This path is used when running remote (server-side) jobs and, therefore, has to
|
|
@@ -112,8 +128,7 @@ class ProjectConfiguration(YamlConfig):
|
|
|
112
128
|
right_camera_index: int = 2
|
|
113
129
|
"""The index of the right body camera in the list of all available OpenCV-managed cameras."""
|
|
114
130
|
harvesters_cti_path: str | Path = Path("/opt/mvIMPACT_Acquire/lib/x86_64/mvGenTLProducer.cti")
|
|
115
|
-
"""The path to the GeniCam CTI file used to connect to Harvesters-managed cameras.
|
|
116
|
-
the face camera."""
|
|
131
|
+
"""The path to the GeniCam CTI file used to connect to Harvesters-managed cameras."""
|
|
117
132
|
actor_port: str = "/dev/ttyACM0"
|
|
118
133
|
"""The USB port used by the Actor Microcontroller."""
|
|
119
134
|
sensor_port: str = "/dev/ttyACM1"
|
|
@@ -125,10 +140,10 @@ class ProjectConfiguration(YamlConfig):
|
|
|
125
140
|
lickport_port: str = "/dev/ttyUSB1"
|
|
126
141
|
"""The USB port used by the LickPort Zaber motor controllers (devices)."""
|
|
127
142
|
unity_ip: str = "127.0.0.1"
|
|
128
|
-
"""The IP address of the MQTT broker used to communicate with the Unity game engine.
|
|
143
|
+
"""The IP address of the MQTT broker used to communicate with the Unity game engine. This is only used during
|
|
129
144
|
experiment runtimes. Training runtimes ignore this parameter."""
|
|
130
145
|
unity_port: int = 1883
|
|
131
|
-
"""The port number of the MQTT broker used to communicate with the Unity game engine.
|
|
146
|
+
"""The port number of the MQTT broker used to communicate with the Unity game engine. This is only used during
|
|
132
147
|
experiment runtimes. Training runtimes ignore this parameter."""
|
|
133
148
|
valve_calibration_data: dict[int | float, int | float] | tuple[tuple[int | float, int | float], ...] = (
|
|
134
149
|
(15000, 1.8556),
|
|
@@ -136,46 +151,42 @@ class ProjectConfiguration(YamlConfig):
|
|
|
136
151
|
(45000, 7.1846),
|
|
137
152
|
(60000, 10.0854),
|
|
138
153
|
)
|
|
139
|
-
"""A
|
|
140
|
-
in microliters. During
|
|
141
|
-
times the valve needs to be open to deliver the desired volume.
|
|
154
|
+
"""A tuple of tuples that maps water delivery solenoid valve open times, in microseconds, to the dispensed volume
|
|
155
|
+
of water, in microliters. During training and experiment runtimes, this data is used by the ValveModule to translate
|
|
156
|
+
the requested reward volumes into times the valve needs to be open to deliver the desired volume of water.
|
|
142
157
|
"""
|
|
143
158
|
|
|
144
159
|
@classmethod
|
|
145
160
|
def load(cls, project_name: str, configuration_path: None | Path = None) -> "ProjectConfiguration":
|
|
146
|
-
"""Loads the project configuration parameters from a project_configuration.yaml file
|
|
147
|
-
to initialize the ProjectConfiguration instance.
|
|
161
|
+
"""Loads the project configuration parameters from a project_configuration.yaml file.
|
|
148
162
|
|
|
149
|
-
This method is called
|
|
150
|
-
|
|
151
|
-
configuration file and prompts the user to update the configuration before proceeding with the runtime.
|
|
163
|
+
This method is called during each interaction with any runtime session's data, including the creation of a new
|
|
164
|
+
session. When this method is called for a non-existent (new) project name, it generates the default
|
|
165
|
+
configuration file and prompts the user to update the configuration before proceeding with the runtime. All
|
|
166
|
+
future interactions with the sessions from this project reuse the existing configuration file.
|
|
152
167
|
|
|
153
168
|
Notes:
|
|
154
169
|
As part of its runtime, the method may prompt the user to provide the path to the local root directory.
|
|
155
|
-
This directory stores all project subdirectories and acts as the top level of the
|
|
156
|
-
The path to the directory
|
|
157
|
-
all future projects. Use sl-
|
|
170
|
+
This directory stores all project subdirectories and acts as the top level of the Sun lab data hierarchy.
|
|
171
|
+
The path to the directory is then saved inside user's default data directory, so that it can be reused for
|
|
172
|
+
all future projects. Use sl-replace-root CLI to replace the saved root directory path.
|
|
158
173
|
|
|
159
|
-
Since this class is used
|
|
160
|
-
|
|
161
|
-
|
|
174
|
+
Since this class is used for all Sun lab data structure interactions, this method supports multiple ways of
|
|
175
|
+
loading class data. If this method is called as part of the sl-experiment new session creation pipeline, use
|
|
176
|
+
'project_name' argument. If this method is called as part of the sl-forgery data processing pipeline(s), use
|
|
177
|
+
'configuration_path' argument.
|
|
162
178
|
|
|
163
179
|
Args:
|
|
164
|
-
project_name: The name of the project whose configuration file needs to be discovered and loaded
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
project_name when both are provided.
|
|
180
|
+
project_name: The name of the project whose configuration file needs to be discovered and loaded or, if the
|
|
181
|
+
project does not exist, created.
|
|
182
|
+
configuration_path: Optional. The path to the project_configuration.yaml file from which to load the data.
|
|
183
|
+
This way of resolving the configuration data source always takes precedence over the project_name when
|
|
184
|
+
both are provided.
|
|
170
185
|
|
|
171
186
|
Returns:
|
|
172
|
-
|
|
187
|
+
The initialized ProjectConfiguration instance that stores the configuration data for the target project.
|
|
173
188
|
"""
|
|
174
189
|
|
|
175
|
-
# Ensures console is enabled
|
|
176
|
-
if not console.enabled:
|
|
177
|
-
console.enable()
|
|
178
|
-
|
|
179
190
|
# If the configuration path is not provided, uses the 'default' resolution strategy that involves reading the
|
|
180
191
|
# user's data directory
|
|
181
192
|
if configuration_path is None:
|
|
@@ -192,6 +203,7 @@ class ProjectConfiguration(YamlConfig):
|
|
|
192
203
|
"directory that stores all project-specific directories. This is required when resolving project "
|
|
193
204
|
"configuration based on project's name."
|
|
194
205
|
)
|
|
206
|
+
# noinspection PyTypeChecker
|
|
195
207
|
console.echo(message=message, level=LogLevel.WARNING)
|
|
196
208
|
root_path_str = input("Local root path: ")
|
|
197
209
|
root_path = Path(root_path_str)
|
|
@@ -224,13 +236,15 @@ class ProjectConfiguration(YamlConfig):
|
|
|
224
236
|
f"proceeding further to avoid runtime errors. Also, edit other configuration precursors saved to the "
|
|
225
237
|
f"same directory to control other aspects of data acquisition and processing."
|
|
226
238
|
)
|
|
239
|
+
# noinspection PyTypeChecker
|
|
227
240
|
console.echo(message=message, level=LogLevel.WARNING)
|
|
228
241
|
|
|
229
242
|
# Generates the default project configuration instance and dumps it as a .yaml file. Note, as part of
|
|
230
243
|
# this process, the class generates the correct 'local_root_path' based on the path provided by the
|
|
231
244
|
# user.
|
|
232
245
|
precursor = ProjectConfiguration(local_root_directory=Path(str(configuration_path.parents[2])))
|
|
233
|
-
precursor.
|
|
246
|
+
precursor.project_name = project_name
|
|
247
|
+
precursor.save(path=configuration_path)
|
|
234
248
|
|
|
235
249
|
# Waits for the user to manually configure the newly created file.
|
|
236
250
|
input(f"Enter anything to continue: ")
|
|
@@ -263,16 +277,16 @@ class ProjectConfiguration(YamlConfig):
|
|
|
263
277
|
# Returns the initialized class instance to caller
|
|
264
278
|
return instance
|
|
265
279
|
|
|
266
|
-
def
|
|
267
|
-
"""Saves
|
|
280
|
+
def save(self, path: Path) -> None:
|
|
281
|
+
"""Saves class instance data to disk as a project_configuration.yaml file.
|
|
268
282
|
|
|
269
|
-
This method is automatically called when
|
|
270
|
-
|
|
283
|
+
This method is automatically called when a new project is created. After this method's runtime, all future
|
|
284
|
+
calls to the load() method will reuse the configuration data saved to the .yaml file.
|
|
271
285
|
|
|
272
286
|
Notes:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
used during
|
|
287
|
+
When this method is used to generate the configuration .yaml file for a new project, it also generates the
|
|
288
|
+
example 'default_experiment.yaml'. This file is designed to showcase how to write ExperimentConfiguration
|
|
289
|
+
data files that are used to control Mesoscope-VR system states during experiment session runtimes.
|
|
276
290
|
|
|
277
291
|
Args:
|
|
278
292
|
path: The path to the .yaml file to save the data to.
|
|
@@ -301,15 +315,18 @@ class ProjectConfiguration(YamlConfig):
|
|
|
301
315
|
original.to_yaml(file_path=path)
|
|
302
316
|
|
|
303
317
|
# As part of this runtime, also generates and dumps the 'precursor' experiment configuration file.
|
|
304
|
-
|
|
305
|
-
|
|
318
|
+
experiment_configuration_path = path.parent.joinpath("default_experiment.yaml")
|
|
319
|
+
if not experiment_configuration_path.exists():
|
|
320
|
+
example_experiment = ExperimentConfiguration()
|
|
321
|
+
example_experiment.to_yaml(experiment_configuration_path)
|
|
306
322
|
|
|
307
323
|
def _verify_data(self) -> None:
|
|
308
|
-
"""Verifies the data loaded from the project_configuration.yaml file
|
|
324
|
+
"""Verifies the user-modified data loaded from the project_configuration.yaml file.
|
|
309
325
|
|
|
310
326
|
Since this class is explicitly designed to be modified by the user, this verification step is carried out to
|
|
311
327
|
ensure that the loaded data matches expectations. This reduces the potential for user errors to impact the
|
|
312
|
-
runtime behavior of the
|
|
328
|
+
runtime behavior of the libraries using this class. This internal method is automatically called by the load()
|
|
329
|
+
method.
|
|
313
330
|
|
|
314
331
|
Notes:
|
|
315
332
|
The method does not verify all fields loaded from the configuration file and instead focuses on fields that
|
|
@@ -362,7 +379,7 @@ class RawData:
|
|
|
362
379
|
includes .mp4 video files from each recorded camera."""
|
|
363
380
|
mesoscope_data_path: str | Path
|
|
364
381
|
"""Stores the path to the directory that contains all Mesoscope data acquired during the session. Primarily, this
|
|
365
|
-
includes the mesoscope-acquired .
|
|
382
|
+
includes the mesoscope-acquired .tiff files (brain activity data) and the motion estimation data."""
|
|
366
383
|
behavior_data_path: str | Path
|
|
367
384
|
"""Stores the path to the directory that contains all behavior data acquired during the session. Primarily, this
|
|
368
385
|
includes the .npz log files used by data-acquisition libraries to store all acquired data. The data stored in this
|
|
@@ -465,10 +482,10 @@ class RawData:
|
|
|
465
482
|
|
|
466
483
|
Args:
|
|
467
484
|
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
468
|
-
|
|
485
|
+
directory that stores all Sun lab projects on the target machine.
|
|
469
486
|
"""
|
|
470
487
|
# Gets current root from the raw_data_path.
|
|
471
|
-
old_root = Path(self.raw_data_path).parents[
|
|
488
|
+
old_root = Path(self.raw_data_path).parents[3]
|
|
472
489
|
|
|
473
490
|
# Updates all paths by replacing old_root with new_root
|
|
474
491
|
self.raw_data_path = new_root.joinpath(Path(self.raw_data_path).relative_to(old_root))
|
|
@@ -494,9 +511,9 @@ class RawData:
|
|
|
494
511
|
class ProcessedData:
|
|
495
512
|
"""Stores the paths to the directories and files that make up the 'processed_data' session directory.
|
|
496
513
|
|
|
497
|
-
The processed_data directory stores the
|
|
498
|
-
|
|
499
|
-
|
|
514
|
+
The processed_data directory stores the data generated by various processing pipelines from the raw data. Processed
|
|
515
|
+
data represents an intermediate step between raw data and the dataset used in the data analysis, but is not itself
|
|
516
|
+
designed to be analyzed.
|
|
500
517
|
|
|
501
518
|
Notes:
|
|
502
519
|
The paths from this section are typically used only on the BioHPC server. This is because most data processing
|
|
@@ -572,10 +589,10 @@ class ProcessedData:
|
|
|
572
589
|
|
|
573
590
|
Args:
|
|
574
591
|
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
575
|
-
|
|
592
|
+
directory that stores all Sun lab projects on the target machine.
|
|
576
593
|
"""
|
|
577
594
|
# Gets current root from the processed_data_path.
|
|
578
|
-
old_root = Path(self.processed_data_path).parents[
|
|
595
|
+
old_root = Path(self.processed_data_path).parents[3]
|
|
579
596
|
|
|
580
597
|
# Updates all paths by replacing old_root with new_root
|
|
581
598
|
self.processed_data_path = new_root.joinpath(Path(self.processed_data_path).relative_to(old_root))
|
|
@@ -730,30 +747,30 @@ class Destinations:
|
|
|
730
747
|
|
|
731
748
|
@dataclass
|
|
732
749
|
class SessionData(YamlConfig):
|
|
733
|
-
"""
|
|
750
|
+
"""Stores and manages the data layout of a single training or experiment session acquired using the Sun lab
|
|
751
|
+
Mesoscope-VR system.
|
|
734
752
|
|
|
735
|
-
The primary purpose of this class is to maintain the session data structure across all supported destinations
|
|
736
|
-
generates the paths used by all other classes from
|
|
737
|
-
|
|
753
|
+
The primary purpose of this class is to maintain the session data structure across all supported destinations and
|
|
754
|
+
during all processing stages. It generates the paths used by all other classes from all Sun lab libraries that
|
|
755
|
+
interact with the session's data from the point of its creation and until the data is integrated into an
|
|
756
|
+
analysis dataset.
|
|
738
757
|
|
|
739
|
-
|
|
740
|
-
When the class is used to create a new session, it
|
|
741
|
-
UTC timestamp,
|
|
758
|
+
When necessary, the class can be used to either generate a new session or load the layout of an already existing
|
|
759
|
+
session. When the class is used to create a new session, it generates the new session's name using the current
|
|
760
|
+
UTC timestamp, accurate to microseconds. This ensures that each session name is unique and preserves the overall
|
|
742
761
|
session order.
|
|
743
762
|
|
|
744
763
|
Notes:
|
|
745
764
|
If this class is instantiated on the VRPC, it is expected that the BioHPC server, Synology NAS, and ScanImagePC
|
|
746
|
-
data directories are mounted on the local
|
|
747
|
-
with these destinations are carried out with the assumption that the OS has full access to these
|
|
748
|
-
and filesystems.
|
|
749
|
-
|
|
750
|
-
If this class is instantiated on the BioHPC server, some methods from this class will not work as expected. It
|
|
751
|
-
is essential that this class is not used outside the default sl-experiment and sl-forgery library runtimes to
|
|
752
|
-
ensure it is used safely.
|
|
765
|
+
data directories are mounted on the local filesystem via the SMB or equivalent protocol. All manipulations
|
|
766
|
+
with these destinations are carried out with the assumption that the local OS has full access to these
|
|
767
|
+
directories and filesystems.
|
|
753
768
|
|
|
754
769
|
This class is specifically designed for working with the data from a single session, performed by a single
|
|
755
770
|
animal under the specific experiment. The class is used to manage both raw and processed data. It follows the
|
|
756
|
-
data through acquisition, preprocessing and processing stages of the Sun lab data workflow.
|
|
771
|
+
data through acquisition, preprocessing and processing stages of the Sun lab data workflow. Together with
|
|
772
|
+
ProjectConfiguration class, this class serves as an entry point for all interactions with the managed session's
|
|
773
|
+
data.
|
|
757
774
|
"""
|
|
758
775
|
|
|
759
776
|
project_name: str
|
|
@@ -767,67 +784,83 @@ class SessionData(YamlConfig):
|
|
|
767
784
|
to be set to one of the four supported types: 'Lick training', 'Run training', 'Window checking' or 'Experiment'.
|
|
768
785
|
"""
|
|
769
786
|
experiment_name: str | None
|
|
770
|
-
"""Stores the name of the experiment configuration file. If the session_type field is set to 'Experiment'
|
|
771
|
-
field is
|
|
772
|
-
used to load the experiment configuration
|
|
773
|
-
|
|
787
|
+
"""Stores the name of the experiment configuration file. If the session_type field is set to 'Experiment' and this
|
|
788
|
+
field is not None (null), it communicates the specific experiment configuration used by the session. During runtime,
|
|
789
|
+
the name stored here is used to load the specific experiment configuration data stored in a .yaml file with the
|
|
790
|
+
same name. If the session is not an experiment session, this field is ignored."""
|
|
774
791
|
raw_data: RawData
|
|
775
|
-
"""
|
|
776
|
-
|
|
777
|
-
|
|
792
|
+
"""This section stores the paths to various directories and files that make up the raw_data subfolder. This
|
|
793
|
+
subfolder stores all data acquired during training or experiment runtimes before and after preprocessing. Note, the
|
|
794
|
+
preprocessing does not change the raw data in any way other than lossless compression and minor format
|
|
795
|
+
reorganization. Therefore, the data is considered 'raw' both before and after preprocessing."""
|
|
778
796
|
processed_data: ProcessedData
|
|
779
|
-
"""
|
|
780
|
-
|
|
781
|
-
|
|
797
|
+
"""This section stores the paths to various directories used to store processed session data. Processed data is
|
|
798
|
+
generated from raw data by running various processing pipelines, such as suite2p, DeepLabCut and Sun lab's behavior
|
|
799
|
+
parsing pipelines. Typically, all data is processed on the BioHPC server and may be stored on a filesystem volume
|
|
800
|
+
different from the one that stores the raw data."""
|
|
782
801
|
persistent_data: PersistentData
|
|
783
|
-
"""
|
|
784
|
-
transferred to long-term storage destinations.
|
|
802
|
+
"""This section stores the paths to various files and directories that are held back on the VRPC and ScanImagePC
|
|
803
|
+
after the session data is transferred to long-term storage destinations as part of preprocessing. Typically, this
|
|
804
|
+
data is reused during the acquisition of future runtime session data. This section is not used during data
|
|
805
|
+
processing."""
|
|
785
806
|
mesoscope_data: MesoscopeData
|
|
786
|
-
"""
|
|
787
|
-
|
|
807
|
+
"""This section stores the paths to various directories used by the ScanImagePC when acquiring mesoscope-related
|
|
808
|
+
data. During runtime, the VRPC (behavior data and experiment control) and the ScanImagePC (brain activity data and
|
|
809
|
+
Mesoscope control) operate mostly independently of each-other. During preprocessing, the VRPC pulls the data from
|
|
810
|
+
the ScanImagePC, using the paths in this section to find the data to be transferred. This section is not used
|
|
811
|
+
during data processing."""
|
|
788
812
|
destinations: Destinations
|
|
789
|
-
"""
|
|
790
|
-
copied as part of preprocessing
|
|
791
|
-
SMB or equivalent protocol.
|
|
813
|
+
"""This section stores the paths to the destination directories on the BioHPC server and Synology NAS, to which the
|
|
814
|
+
data is copied as part of preprocessing for long-term storage and further processing. Both of these directories
|
|
815
|
+
should be mapped (mounted) to the VRPC's filesystem via the SMB or equivalent protocol. This section is not used
|
|
816
|
+
during data processing."""
|
|
792
817
|
|
|
793
818
|
@classmethod
|
|
794
|
-
def
|
|
819
|
+
def create(
|
|
795
820
|
cls,
|
|
796
821
|
animal_id: str,
|
|
797
822
|
session_type: str,
|
|
798
823
|
project_configuration: ProjectConfiguration,
|
|
799
824
|
experiment_name: str | None = None,
|
|
825
|
+
session_name: str | None = None,
|
|
800
826
|
) -> "SessionData":
|
|
801
|
-
"""Creates a new SessionData object and
|
|
827
|
+
"""Creates a new SessionData object and generates the new session's data structure.
|
|
802
828
|
|
|
803
|
-
This method is
|
|
804
|
-
|
|
805
|
-
preprocessing session's
|
|
829
|
+
This method is called by sl-experiment runtimes that create new training or experiment sessions to generate the
|
|
830
|
+
session data directory tree. It always assumes it is called on the VRPC and, as part of its runtime, resolves
|
|
831
|
+
and generates the necessary local and ScanImagePC directories to support acquiring and preprocessing session's
|
|
832
|
+
data.
|
|
806
833
|
|
|
807
834
|
Notes:
|
|
808
|
-
To load an already existing session data structure, use the
|
|
835
|
+
To load an already existing session data structure, use the load() method instead.
|
|
809
836
|
|
|
810
837
|
This method automatically dumps the data of the created SessionData instance into the session_data.yaml file
|
|
811
838
|
inside the root raw_data directory of the created hierarchy. It also finds and dumps other configuration
|
|
812
|
-
files, such as project_configuration.yaml
|
|
813
|
-
This
|
|
839
|
+
files, such as project_configuration.yaml and experiment_configuration.yaml, into the same raw_data
|
|
840
|
+
directory. This ensures that if the session's runtime is interrupted unexpectedly, the acquired data can
|
|
841
|
+
still be processed.
|
|
814
842
|
|
|
815
843
|
Args:
|
|
816
844
|
animal_id: The ID code of the animal for which the data is acquired.
|
|
817
845
|
session_type: The type of the session. Primarily, this determines how to read the session_descriptor.yaml
|
|
818
|
-
file. Valid options are 'Lick training', 'Run training', or 'Experiment'.
|
|
819
|
-
experiment_name: The name of the experiment
|
|
820
|
-
for 'Experiment' session types. It is used to find the
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
846
|
+
file. Valid options are 'Lick training', 'Run training', 'Window checking', or 'Experiment'.
|
|
847
|
+
experiment_name: The name of the experiment executed during managed session. This optional argument is only
|
|
848
|
+
used for 'Experiment' session types. It is used to find the experiment configuration .YAML file.
|
|
849
|
+
project_configuration: The initialized ProjectConfiguration instance that stores the session's project
|
|
850
|
+
configuration data. This is used to determine the root directory paths for all lab machines used during
|
|
851
|
+
data acquisition and processing.
|
|
852
|
+
session_name: An optional session_name override. Generally, this argument should not be provided for most
|
|
853
|
+
sessions. When provided, the method uses this name instead of generating a new timestamp-based name.
|
|
854
|
+
This is only used during the 'ascension' runtime to convert old data structures to the modern
|
|
855
|
+
lab standards.
|
|
824
856
|
|
|
825
857
|
Returns:
|
|
826
|
-
An initialized SessionData instance
|
|
858
|
+
An initialized SessionData instance that stores the layout of the newly created session's data.
|
|
827
859
|
"""
|
|
828
860
|
|
|
829
861
|
# Acquires the UTC timestamp to use as the session name
|
|
830
|
-
session_name
|
|
862
|
+
if session_name is None:
|
|
863
|
+
session_name = str(get_timestamp(time_separator="-"))
|
|
831
864
|
|
|
832
865
|
# Extracts the root directory paths stored inside the project configuration file. All roots are expected to be
|
|
833
866
|
# mounted on the local (VRPC) via SMB or equivalent protocol and be relative to the VRPC root.
|
|
@@ -924,7 +957,7 @@ class SessionData(YamlConfig):
|
|
|
924
957
|
|
|
925
958
|
# Saves the configured instance data to the session's folder, so that it can be reused during processing or
|
|
926
959
|
# preprocessing
|
|
927
|
-
instance.
|
|
960
|
+
instance._save()
|
|
928
961
|
|
|
929
962
|
# Extracts and saves the necessary configuration classes to the session raw_data folder. Note, this list of
|
|
930
963
|
# classes is not exhaustive. More classes are saved as part of the session runtime management class start() and
|
|
@@ -950,30 +983,31 @@ class SessionData(YamlConfig):
|
|
|
950
983
|
return instance
|
|
951
984
|
|
|
952
985
|
@classmethod
|
|
953
|
-
def
|
|
986
|
+
def load(
|
|
954
987
|
cls,
|
|
955
988
|
session_path: Path,
|
|
956
989
|
on_server: bool,
|
|
957
990
|
) -> "SessionData":
|
|
958
|
-
"""Loads the SessionData instance from the session_data.yaml file
|
|
991
|
+
"""Loads the SessionData instance from the target session's session_data.yaml file.
|
|
959
992
|
|
|
960
|
-
This method is used to load the data
|
|
961
|
-
or processing
|
|
962
|
-
resolves all necessary paths and creates the necessary directories.
|
|
993
|
+
This method is used to load the data layout information of an already existing session. Primarily, this is used
|
|
994
|
+
when preprocessing or processing session data. Depending on the call location (machine), the method
|
|
995
|
+
automatically resolves all necessary paths and creates the necessary directories.
|
|
963
996
|
|
|
964
997
|
Notes:
|
|
965
|
-
To create a new session, use the
|
|
998
|
+
To create a new session, use the create() method instead.
|
|
966
999
|
|
|
967
1000
|
Args:
|
|
968
1001
|
session_path: The path to the root directory of an existing session, e.g.: vrpc_root/project/animal/session.
|
|
969
1002
|
on_server: Determines whether the method is used to initialize an existing session on the VRPC or the
|
|
970
|
-
BioHPC server.
|
|
1003
|
+
BioHPC server. Note, VRPC runtimes use the same 'root' directory to store raw_data and processed_data
|
|
1004
|
+
subfolders. BioHPC server runtimes use different volumes (drives) to store these subfolders.
|
|
971
1005
|
|
|
972
1006
|
Returns:
|
|
973
1007
|
An initialized SessionData instance for the session whose data is stored at the provided path.
|
|
974
1008
|
|
|
975
1009
|
Raises:
|
|
976
|
-
FileNotFoundError: If the 'session_data.yaml' file is not found
|
|
1010
|
+
FileNotFoundError: If the 'session_data.yaml' file is not found under the session_path/raw_data/ subfolder.
|
|
977
1011
|
"""
|
|
978
1012
|
# To properly initialize the SessionData instance, the provided path should contain the raw_data directory
|
|
979
1013
|
# with session_data.yaml file.
|
|
@@ -988,13 +1022,13 @@ class SessionData(YamlConfig):
|
|
|
988
1022
|
console.error(message=message, error=FileNotFoundError)
|
|
989
1023
|
|
|
990
1024
|
# Loads class data from .yaml
|
|
991
|
-
instance: SessionData = cls.from_yaml(file_path=
|
|
1025
|
+
instance: SessionData = cls.from_yaml(file_path=session_data_path) # type: ignore
|
|
992
1026
|
|
|
993
1027
|
# The method assumes that the 'donor' .yaml file is always stored inside the raw_data directory of the session
|
|
994
1028
|
# to be processed. Since the directory itself might have moved (between or even within the same PC) relative to
|
|
995
1029
|
# where it was when the SessionData snapshot was generated, reconfigures the paths to all raw_data files using
|
|
996
1030
|
# the root from above.
|
|
997
|
-
instance.raw_data.switch_root(new_root=session_path)
|
|
1031
|
+
instance.raw_data.switch_root(new_root=session_path.parents[2])
|
|
998
1032
|
|
|
999
1033
|
# Resolves the paths to the processed_data directories. The resolution strategy depends on whether the method is
|
|
1000
1034
|
# called on the VRPC (locally) or the BioHPC server (remotely).
|
|
@@ -1002,7 +1036,7 @@ class SessionData(YamlConfig):
|
|
|
1002
1036
|
# Local runtimes use the same root session directory for both raw_data and processed_data. This stems from
|
|
1003
1037
|
# the assumption that most local machines in the lab only use NVME (fast) volumes and, therefore, do not
|
|
1004
1038
|
# need to separate 'storage' and 'working' data.
|
|
1005
|
-
instance.processed_data.switch_root(new_root=session_path)
|
|
1039
|
+
instance.processed_data.switch_root(new_root=session_path.parents[2])
|
|
1006
1040
|
|
|
1007
1041
|
else:
|
|
1008
1042
|
# The BioHPC server stores raw_data on slow volume and processed_data on fast (NVME) volume. Therefore, to
|
|
@@ -1020,12 +1054,12 @@ class SessionData(YamlConfig):
|
|
|
1020
1054
|
# Returns the initialized SessionData instance to caller
|
|
1021
1055
|
return instance
|
|
1022
1056
|
|
|
1023
|
-
def
|
|
1057
|
+
def _save(self) -> None:
|
|
1024
1058
|
"""Saves the instance data to the 'raw_data' directory of the managed session as a 'session_data.yaml' file.
|
|
1025
1059
|
|
|
1026
1060
|
This is used to save the data stored in the instance to disk, so that it can be reused during preprocessing or
|
|
1027
1061
|
data processing. The method is intended to only be used by the SessionData instance itself during its
|
|
1028
|
-
|
|
1062
|
+
create() method runtime.
|
|
1029
1063
|
"""
|
|
1030
1064
|
|
|
1031
1065
|
# Copies instance data to prevent it from being modified by reference when executing the steps below
|
|
@@ -101,6 +101,7 @@ def calculate_directory_checksum(
|
|
|
101
101
|
process_file = partial(_calculate_file_checksum, directory)
|
|
102
102
|
|
|
103
103
|
# Submits all tasks to be executed in parallel
|
|
104
|
+
# noinspection PyTypeChecker
|
|
104
105
|
future_to_path = {executor.submit(process_file, file): file for file in files}
|
|
105
106
|
|
|
106
107
|
# Collects results as they complete
|