sl-shared-assets 1.0.0rc4__py3-none-any.whl → 1.0.0rc6__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/data_classes.py +85 -59
- sl_shared_assets/data_classes.pyi +666 -0
- {sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/METADATA +1 -1
- {sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/RECORD +7 -6
- {sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/WHEEL +0 -0
- {sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/entry_points.txt +0 -0
- {sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/licenses/LICENSE +0 -0
sl_shared_assets/data_classes.py
CHANGED
|
@@ -87,7 +87,7 @@ class ProjectConfiguration(YamlConfig):
|
|
|
87
87
|
local_root_directory: str | Path = Path("/media/Data/Experiments")
|
|
88
88
|
"""The absolute path to the root directory where all projects are stored on the local host-machine (VRPC). Note,
|
|
89
89
|
overwriting the value of this field is pointless, as it is automatically set each time the class is instantiated."""
|
|
90
|
-
local_server_directory: str | Path = Path("/
|
|
90
|
+
local_server_directory: str | Path = Path("/home/cybermouse/server/storage/sun_data")
|
|
91
91
|
"""The absolute path to the locally-mapped (via SMB protocol) root BioHPC server machine directory where to store
|
|
92
92
|
all projects."""
|
|
93
93
|
local_nas_directory: str | Path = Path("/home/cybermouse/nas/rawdata")
|
|
@@ -205,12 +205,9 @@ class ProjectConfiguration(YamlConfig):
|
|
|
205
205
|
with open(path_file, "w") as f:
|
|
206
206
|
f.write(str(root_path))
|
|
207
207
|
|
|
208
|
-
#
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
# Reads the root path from the file
|
|
212
|
-
with open(path_file, "r") as f:
|
|
213
|
-
root_path = Path(f.read().strip())
|
|
208
|
+
# Once the location of the path storage file is resolved, reads the root path from the file
|
|
209
|
+
with open(path_file, "r") as f:
|
|
210
|
+
root_path = Path(f.read().strip())
|
|
214
211
|
|
|
215
212
|
# Uses the root experiment directory path to generate the path to the target project's configuration file.
|
|
216
213
|
configuration_path = root_path.joinpath(project_name, "configuration", "project_configuration.yaml")
|
|
@@ -459,8 +456,8 @@ class RawData:
|
|
|
459
456
|
|
|
460
457
|
This service method is used by the SessionData class to convert all paths in this class to be relative to the
|
|
461
458
|
new root. This is used to adjust the SessionData instance to work for the VRPC (one root) or the BioHPC server
|
|
462
|
-
(another root).
|
|
463
|
-
|
|
459
|
+
(another root). This method is only implemented for subclasses intended to be used both locally and on the
|
|
460
|
+
BioHPC server.
|
|
464
461
|
|
|
465
462
|
Args:
|
|
466
463
|
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
@@ -494,15 +491,20 @@ class ProcessedData:
|
|
|
494
491
|
"""Stores the paths to the directories and files that make up the 'processed_data' session directory.
|
|
495
492
|
|
|
496
493
|
The processed_data directory stores the processed session data, which is generated by running various processing
|
|
497
|
-
pipelines
|
|
498
|
-
|
|
499
|
-
|
|
494
|
+
pipelines. These pipelines use raw data to generate processed data, which represents an intermediate step between
|
|
495
|
+
raw data and the dataset used in the data analysis.
|
|
496
|
+
|
|
497
|
+
Notes:
|
|
498
|
+
The paths from this section are typically used only on the BioHPC server. This is because most data processing
|
|
499
|
+
in the lab is performed using the processing server's resources. On the server, processed data is stored on
|
|
500
|
+
the fast volume, in contrast to raw data, which is stored on the slow volume. However, to support local testing,
|
|
501
|
+
the class resolves the paths in this section both locally and globally (on the server).
|
|
502
|
+
|
|
500
503
|
"""
|
|
501
504
|
|
|
502
505
|
processed_data_path: str | Path
|
|
503
506
|
"""Stores the path to the root processed_data directory of the session. This directory stores the processed data
|
|
504
|
-
as it is generated by various
|
|
505
|
-
server and is not intended to be used directly for data analysis."""
|
|
507
|
+
as it is generated by various data processing pipelines."""
|
|
506
508
|
camera_data_path: str | Path
|
|
507
509
|
"""Stores the output of the DeepLabCut pose estimation pipeline."""
|
|
508
510
|
mesoscope_data_path: str | Path
|
|
@@ -556,6 +558,29 @@ class ProcessedData:
|
|
|
556
558
|
ensure_directory_exists(Path(self.deeplabcut_root_path))
|
|
557
559
|
ensure_directory_exists(Path(self.suite2p_configuration_path))
|
|
558
560
|
|
|
561
|
+
def switch_root(self, new_root: Path) -> None:
|
|
562
|
+
"""Changes the root of the managed processed_data directory to the provided root path.
|
|
563
|
+
|
|
564
|
+
This service method is used by the SessionData class to convert all paths in this class to be relative to the
|
|
565
|
+
new root. This is used to adjust the SessionData instance to work for the VRPC (one root) or the BioHPC server
|
|
566
|
+
(another root). This method is only implemented for subclasses intended to be used both locally and on the
|
|
567
|
+
BioHPC server.
|
|
568
|
+
|
|
569
|
+
Args:
|
|
570
|
+
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
571
|
+
root session directory: pc_root/project/animal/session.
|
|
572
|
+
"""
|
|
573
|
+
# Gets current root from the processed_data_path.
|
|
574
|
+
old_root = Path(self.processed_data_path).parents[2]
|
|
575
|
+
|
|
576
|
+
# Updates all paths by replacing old_root with new_root
|
|
577
|
+
self.processed_data_path = new_root.joinpath(Path(self.processed_data_path).relative_to(old_root))
|
|
578
|
+
self.camera_data_path = new_root.joinpath(Path(self.camera_data_path).relative_to(old_root))
|
|
579
|
+
self.mesoscope_data_path = new_root.joinpath(Path(self.mesoscope_data_path).relative_to(old_root))
|
|
580
|
+
self.behavior_data_path = new_root.joinpath(Path(self.behavior_data_path).relative_to(old_root))
|
|
581
|
+
self.deeplabcut_root_path = new_root.joinpath(Path(self.deeplabcut_root_path).relative_to(old_root))
|
|
582
|
+
self.suite2p_configuration_path = new_root.joinpath(Path(self.suite2p_configuration_path).relative_to(old_root))
|
|
583
|
+
|
|
559
584
|
|
|
560
585
|
@dataclass()
|
|
561
586
|
class PersistentData:
|
|
@@ -727,33 +752,36 @@ class SessionData(YamlConfig):
|
|
|
727
752
|
data through acquisition, preprocessing and processing stages of the Sun lab data workflow.
|
|
728
753
|
"""
|
|
729
754
|
|
|
755
|
+
project_name: str
|
|
756
|
+
"""Stores the name of the managed session's project."""
|
|
730
757
|
animal_id: str
|
|
731
758
|
"""Stores the unique identifier of the animal that participates in the managed session."""
|
|
732
759
|
session_name: str
|
|
733
760
|
"""Stores the name (timestamp-based ID) of the managed session."""
|
|
734
761
|
session_type: str
|
|
735
762
|
"""Stores the type of the session. Primarily, this determines how to read the session_descriptor.yaml file. Has
|
|
736
|
-
to be set to one of the
|
|
763
|
+
to be set to one of the four supported types: 'Lick training', 'Run training', 'Window checking' or 'Experiment'.
|
|
737
764
|
"""
|
|
738
765
|
experiment_name: str | None
|
|
739
766
|
"""Stores the name of the experiment configuration file. If the session_type field is set to 'Experiment', this
|
|
740
767
|
field is used to communicate the specific experiment configuration used by the session. During runtime, this is
|
|
741
768
|
used to load the experiment configuration (to run the experiment) and to save the experiment configuration to the
|
|
742
769
|
session raw_data folder. If the session is not an experiment session, this is statically set to None."""
|
|
743
|
-
raw_data: RawData
|
|
770
|
+
raw_data: RawData
|
|
744
771
|
"""Stores the paths to various directories and files used to store raw and preprocessed session data. Depending on
|
|
745
772
|
class initialization location (VRPC or BioHPC server), the class automatically resolves the root directory path to
|
|
746
773
|
either the VRPC project directory or the BioHPC cluster storage volume."""
|
|
747
|
-
processed_data: ProcessedData
|
|
748
|
-
"""Stores the paths to various directories used to store processed session data.
|
|
749
|
-
resolved
|
|
750
|
-
|
|
774
|
+
processed_data: ProcessedData
|
|
775
|
+
"""Stores the paths to various directories used to store processed session data. Note, when this section is
|
|
776
|
+
resolved for VRPC, it uses the same local session directory as the raw_data folder. When this is resolved for the
|
|
777
|
+
BioHPC server, it uses the 'fast' volume path."""
|
|
778
|
+
persistent_data: PersistentData
|
|
751
779
|
"""Stores the paths to various files and directories kept on VRPC and ScanImagePC after the session data is
|
|
752
780
|
transferred to long-term storage destinations."""
|
|
753
|
-
mesoscope_data: MesoscopeData
|
|
781
|
+
mesoscope_data: MesoscopeData
|
|
754
782
|
"""Stores the paths to various directories used by the ScanImagePC to store mesoscope-acquired session data,
|
|
755
783
|
before it is moved to the VRPC during preprocessing."""
|
|
756
|
-
destinations: Destinations
|
|
784
|
+
destinations: Destinations
|
|
757
785
|
"""Stores the paths to the destination directories on the BioHPC server and Synology NAS, to which the data is
|
|
758
786
|
copied as part of preprocessing. Both of these directories should be accessible for the VRPC's filesystem via an
|
|
759
787
|
SMB or equivalent protocol."""
|
|
@@ -804,16 +832,11 @@ class SessionData(YamlConfig):
|
|
|
804
832
|
biohpc_root = Path(project_configuration.local_server_directory)
|
|
805
833
|
nas_root = Path(project_configuration.local_nas_directory)
|
|
806
834
|
|
|
807
|
-
# Also extracts the path to fast (working) directory on the BioHPC server. This is used to configure the
|
|
808
|
-
# paths for data processing, which happens on the server.
|
|
809
|
-
biohpc_workdir = Path(project_configuration.remote_working_directory)
|
|
810
|
-
|
|
811
835
|
# Extracts the name of the project stored inside the project configuration file.
|
|
812
836
|
project_name = project_configuration.project_name
|
|
813
837
|
|
|
814
838
|
# Constructs the session directory path and generates the directory
|
|
815
839
|
session_path = vrpc_root.joinpath(project_name, animal_id, session_name)
|
|
816
|
-
remote_session_path = biohpc_workdir.joinpath(project_name, animal_id, session_name)
|
|
817
840
|
|
|
818
841
|
# Handles potential session name conflicts
|
|
819
842
|
counter = 0
|
|
@@ -821,7 +844,6 @@ class SessionData(YamlConfig):
|
|
|
821
844
|
counter += 1
|
|
822
845
|
new_session_name = f"{session_name}_{counter}"
|
|
823
846
|
session_path = vrpc_root.joinpath(project_name, animal_id, new_session_name)
|
|
824
|
-
remote_session_path = biohpc_workdir.joinpath(project_name, animal_id, new_session_name)
|
|
825
847
|
|
|
826
848
|
# If a conflict is detected and resolved, warns the user about the resolved conflict.
|
|
827
849
|
if counter > 0:
|
|
@@ -852,14 +874,12 @@ class SessionData(YamlConfig):
|
|
|
852
874
|
raw_data.make_dirs() # Generates the local directory tree
|
|
853
875
|
|
|
854
876
|
processed_data = ProcessedData(
|
|
855
|
-
processed_data_path=
|
|
856
|
-
camera_data_path=
|
|
857
|
-
mesoscope_data_path=
|
|
858
|
-
behavior_data_path=
|
|
859
|
-
deeplabcut_root_path=
|
|
860
|
-
suite2p_configuration_path=
|
|
861
|
-
project_name, "configuration", "suite2p_configuration.yaml"
|
|
862
|
-
),
|
|
877
|
+
processed_data_path=session_path.joinpath("processed_data"),
|
|
878
|
+
camera_data_path=session_path.joinpath("processed_data", "camera_data"),
|
|
879
|
+
mesoscope_data_path=session_path.joinpath("processed_data", "mesoscope_data"),
|
|
880
|
+
behavior_data_path=session_path.joinpath("processed_data", "behavior_data"),
|
|
881
|
+
deeplabcut_root_path=vrpc_root.joinpath(project_name, "deeplabcut"),
|
|
882
|
+
suite2p_configuration_path=vrpc_root.joinpath(project_name, "configuration", "suite2p_configuration.yaml"),
|
|
863
883
|
)
|
|
864
884
|
|
|
865
885
|
vrpc_persistent_path = vrpc_root.joinpath(project_name, animal_id, "persistent_data")
|
|
@@ -886,6 +906,7 @@ class SessionData(YamlConfig):
|
|
|
886
906
|
|
|
887
907
|
# Packages the sections generated above into a SessionData instance
|
|
888
908
|
instance = SessionData(
|
|
909
|
+
project_name=project_configuration.project_name,
|
|
889
910
|
animal_id=animal_id,
|
|
890
911
|
session_name=session_name,
|
|
891
912
|
session_type=session_type,
|
|
@@ -901,10 +922,6 @@ class SessionData(YamlConfig):
|
|
|
901
922
|
# preprocessing
|
|
902
923
|
instance._to_path()
|
|
903
924
|
|
|
904
|
-
# Removes the processed_data section, as it is not used on the VRPC. This makes it impossible to accidentally
|
|
905
|
-
# interact with this section without errors.
|
|
906
|
-
instance.processed_data = None
|
|
907
|
-
|
|
908
925
|
# Extracts and saves the necessary configuration classes to the session raw_data folder. Note, this list of
|
|
909
926
|
# classes is not exhaustive. More classes are saved as part of the session runtime management class start() and
|
|
910
927
|
# __init__() method runtimes:
|
|
@@ -916,13 +933,13 @@ class SessionData(YamlConfig):
|
|
|
916
933
|
# Project Configuration
|
|
917
934
|
sh.copy2(
|
|
918
935
|
src=vrpc_configuration_path.joinpath("project_configuration.yaml"),
|
|
919
|
-
dst=instance.raw_data.project_configuration_path,
|
|
936
|
+
dst=instance.raw_data.project_configuration_path,
|
|
920
937
|
)
|
|
921
938
|
# Experiment Configuration, if the session type is Experiment.
|
|
922
939
|
if experiment_name is not None:
|
|
923
940
|
sh.copy2(
|
|
924
941
|
src=vrpc_configuration_path.joinpath(f"{experiment_name}.yaml"),
|
|
925
|
-
dst=instance.raw_data.experiment_configuration_path,
|
|
942
|
+
dst=instance.raw_data.experiment_configuration_path,
|
|
926
943
|
)
|
|
927
944
|
|
|
928
945
|
# Returns the initialized SessionData instance to caller
|
|
@@ -969,23 +986,32 @@ class SessionData(YamlConfig):
|
|
|
969
986
|
# Loads class data from .yaml
|
|
970
987
|
instance: SessionData = cls.from_yaml(file_path=session_path) # type: ignore
|
|
971
988
|
|
|
972
|
-
#
|
|
973
|
-
#
|
|
974
|
-
#
|
|
975
|
-
#
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
#
|
|
984
|
-
instance.
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
#
|
|
988
|
-
|
|
989
|
+
# The method assumes that the 'donor' .yaml file is always stored inside the raw_data directory of the session
|
|
990
|
+
# to be processed. Since the directory itself might have moved (between or even within the same PC) relative to
|
|
991
|
+
# where it was when the SessionData snapshot was generated, reconfigures the paths to all raw_data files using
|
|
992
|
+
# the root from above.
|
|
993
|
+
instance.raw_data.switch_root(new_root=session_path)
|
|
994
|
+
|
|
995
|
+
# Resolves the paths to the processed_data directories. The resolution strategy depends on whether the method is
|
|
996
|
+
# called on the VRPC (locally) or the BioHPC server (remotely).
|
|
997
|
+
if not on_server:
|
|
998
|
+
# Local runtimes use the same root session directory for both raw_data and processed_data. This stems from
|
|
999
|
+
# the assumption that most local machines in the lab only use NVME (fast) volumes and, therefore, do not
|
|
1000
|
+
# need to separate 'storage' and 'working' data.
|
|
1001
|
+
instance.processed_data.switch_root(new_root=session_path)
|
|
1002
|
+
|
|
1003
|
+
else:
|
|
1004
|
+
# The BioHPC server stores raw_data on slow volume and processed_data on fast (NVME) volume. Therefore, to
|
|
1005
|
+
# configure processed_data paths, the method first needs to load the fast volume root path from the
|
|
1006
|
+
# project_configuration.yaml file stored in the raw_data folder.
|
|
1007
|
+
project_configuration: ProjectConfiguration = ProjectConfiguration.load(
|
|
1008
|
+
project_name=instance.project_name,
|
|
1009
|
+
configuration_path=Path(instance.raw_data.project_configuration_path),
|
|
1010
|
+
)
|
|
1011
|
+
instance.processed_data.switch_root(new_root=Path(project_configuration.remote_working_directory))
|
|
1012
|
+
|
|
1013
|
+
# Generates processed_data directories
|
|
1014
|
+
instance.processed_data.make_dirs()
|
|
989
1015
|
|
|
990
1016
|
# Returns the initialized SessionData instance to caller
|
|
991
1017
|
return instance
|
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from dataclasses import field, dataclass
|
|
3
|
+
|
|
4
|
+
from _typeshed import Incomplete
|
|
5
|
+
from ataraxis_data_structures import YamlConfig
|
|
6
|
+
|
|
7
|
+
def replace_root_path(path: Path) -> None:
|
|
8
|
+
"""Replaces the path to the local root directory used to store all Sun lab projects with the provided path.
|
|
9
|
+
|
|
10
|
+
When ProjectConfiguration class is instantiated for the first time on a new machine, it asks the user to provide
|
|
11
|
+
the path to the local directory where to save all Sun lab projects. This path is then stored inside the default
|
|
12
|
+
user data directory as a .yaml file to be reused for all future projects. To support replacing this path without
|
|
13
|
+
searching for the user data directory, which is usually hidden, this function finds and updates the contents of the
|
|
14
|
+
file that stores the local root path.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
path: The path to the new local root directory.
|
|
18
|
+
"""
|
|
19
|
+
@dataclass()
|
|
20
|
+
class ProjectConfiguration(YamlConfig):
|
|
21
|
+
"""Stores the project-specific configuration parameters that do not change between different animals and runtime
|
|
22
|
+
sessions.
|
|
23
|
+
|
|
24
|
+
An instance of this class is generated and saved as a .yaml file in the \'configuration\' directory of each project
|
|
25
|
+
when it is created. After that, the stored data is reused for every runtime (training or experiment session) carried
|
|
26
|
+
out for each animal of the project.
|
|
27
|
+
|
|
28
|
+
Notes:
|
|
29
|
+
This class allows flexibly configuring sl_experiment and sl_forgery libraries for different projects in the
|
|
30
|
+
Sun lab. This allows hiding most inner workings of all libraries from the end-users, while providing a robust,
|
|
31
|
+
machine-independent way to interface with all data acquisition and processing libraries.
|
|
32
|
+
|
|
33
|
+
Most lab projects only need to adjust the "surgery_sheet_id" and "water_log_sheet_id" fields of the class.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
project_name: str = ...
|
|
37
|
+
surgery_sheet_id: str = ...
|
|
38
|
+
water_log_sheet_id: str = ...
|
|
39
|
+
google_credentials_path: str | Path = ...
|
|
40
|
+
server_credentials_path: str | Path = ...
|
|
41
|
+
local_root_directory: str | Path = ...
|
|
42
|
+
local_server_directory: str | Path = ...
|
|
43
|
+
local_nas_directory: str | Path = ...
|
|
44
|
+
local_mesoscope_directory: str | Path = ...
|
|
45
|
+
remote_storage_directory: str | Path = ...
|
|
46
|
+
remote_working_directory: str | Path = ...
|
|
47
|
+
face_camera_index: int = ...
|
|
48
|
+
left_camera_index: int = ...
|
|
49
|
+
right_camera_index: int = ...
|
|
50
|
+
harvesters_cti_path: str | Path = ...
|
|
51
|
+
actor_port: str = ...
|
|
52
|
+
sensor_port: str = ...
|
|
53
|
+
encoder_port: str = ...
|
|
54
|
+
headbar_port: str = ...
|
|
55
|
+
lickport_port: str = ...
|
|
56
|
+
unity_ip: str = ...
|
|
57
|
+
unity_port: int = ...
|
|
58
|
+
valve_calibration_data: dict[int | float, int | float] | tuple[tuple[int | float, int | float], ...] = ...
|
|
59
|
+
@classmethod
|
|
60
|
+
def load(cls, project_name: str, configuration_path: None | Path = None) -> ProjectConfiguration:
|
|
61
|
+
"""Loads the project configuration parameters from a project_configuration.yaml file and uses the loaded data
|
|
62
|
+
to initialize the ProjectConfiguration instance.
|
|
63
|
+
|
|
64
|
+
This method is called for each session runtime to reuse the configuration parameters generated at project
|
|
65
|
+
creation. When it is called for the first time (during new project creation), the method generates the default
|
|
66
|
+
configuration file and prompts the user to update the configuration before proceeding with the runtime.
|
|
67
|
+
|
|
68
|
+
Notes:
|
|
69
|
+
As part of its runtime, the method may prompt the user to provide the path to the local root directory.
|
|
70
|
+
This directory stores all project subdirectories and acts as the top level of the local data hierarchy.
|
|
71
|
+
The path to the directory will be saved inside user's default data directory, so that it can be reused for
|
|
72
|
+
all future projects. Use sl-replace_root_path CLI to replace the path that is saved in this way.
|
|
73
|
+
|
|
74
|
+
Since this class is used during both data acquisition and processing on different machines, this method
|
|
75
|
+
supports multiple ways of initializing the class. Use the project_name on the VRPC (via the sl_experiment
|
|
76
|
+
library). Use the configuration path on the BioHPC server (via the sl_forgery library).
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
project_name: The name of the project whose configuration file needs to be discovered and loaded. Note, this
|
|
80
|
+
way of resolving the project is the default way on the VRPC. When processing data on the server, the
|
|
81
|
+
pipeline preferentially uses the configuration_path.
|
|
82
|
+
configuration_path: The path to the project_configuration.yaml file from which to load the data. This is
|
|
83
|
+
an optional way of resolving the configuration data source that always takes precedence over the
|
|
84
|
+
project_name when both are provided.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
An initialized ProjectConfiguration instance.
|
|
88
|
+
"""
|
|
89
|
+
def _to_path(self, path: Path) -> None:
|
|
90
|
+
"""Saves the instance data to disk as a project_configuration.yaml file.
|
|
91
|
+
|
|
92
|
+
This method is automatically called when the project is created. All future runtimes should use the load()
|
|
93
|
+
method to load and reuse the configuration data saved to the .yaml file.
|
|
94
|
+
|
|
95
|
+
Notes:
|
|
96
|
+
This method also generates and dumps multiple other 'precursor' configuration files into the folder. This
|
|
97
|
+
includes the example 'default' experiment configuration and the DeepLabCut and Suite2P configuration files
|
|
98
|
+
used during data processing.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
path: The path to the .yaml file to save the data to.
|
|
102
|
+
"""
|
|
103
|
+
def _verify_data(self) -> None:
|
|
104
|
+
"""Verifies the data loaded from the project_configuration.yaml file to ensure its validity.
|
|
105
|
+
|
|
106
|
+
Since this class is explicitly designed to be modified by the user, this verification step is carried out to
|
|
107
|
+
ensure that the loaded data matches expectations. This reduces the potential for user errors to impact the
|
|
108
|
+
runtime behavior of the library. This internal method is automatically called by the load() method.
|
|
109
|
+
|
|
110
|
+
Notes:
|
|
111
|
+
The method does not verify all fields loaded from the configuration file and instead focuses on fields that
|
|
112
|
+
do not have valid default values. Since these fields are expected to be frequently modified by users, they
|
|
113
|
+
are the ones that require additional validation.
|
|
114
|
+
|
|
115
|
+
Raises:
|
|
116
|
+
ValueError: If the loaded data does not match expected formats or values.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
@dataclass()
|
|
120
|
+
class RawData:
|
|
121
|
+
"""Stores the paths to the directories and files that make up the 'raw_data' session directory.
|
|
122
|
+
|
|
123
|
+
The raw_data directory stores the data acquired during the session runtime before and after preprocessing. Since
|
|
124
|
+
preprocessing does not alter the data, any data in that folder is considered 'raw'. The raw_data folder is initially
|
|
125
|
+
created on the VRPC and, after preprocessing, is copied to the BioHPC server and the Synology NAS for long-term
|
|
126
|
+
storage and further processing.
|
|
127
|
+
|
|
128
|
+
Notes:
|
|
129
|
+
The overall structure of the raw_data directory remains fixed for the entire lifetime of the data. It is reused
|
|
130
|
+
across all destinations.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
raw_data_path: str | Path
|
|
134
|
+
camera_data_path: str | Path
|
|
135
|
+
mesoscope_data_path: str | Path
|
|
136
|
+
behavior_data_path: str | Path
|
|
137
|
+
zaber_positions_path: str | Path
|
|
138
|
+
session_descriptor_path: str | Path
|
|
139
|
+
hardware_configuration_path: str | Path
|
|
140
|
+
surgery_metadata_path: str | Path
|
|
141
|
+
project_configuration_path: str | Path
|
|
142
|
+
session_data_path: str | Path
|
|
143
|
+
experiment_configuration_path: str | Path
|
|
144
|
+
mesoscope_positions_path: str | Path
|
|
145
|
+
window_screenshot_path: str | Path
|
|
146
|
+
def __post_init__(self) -> None:
|
|
147
|
+
"""This method is automatically called after class instantiation and ensures that all path fields of the class
|
|
148
|
+
are converted to Path objects.
|
|
149
|
+
"""
|
|
150
|
+
def make_string(self) -> None:
|
|
151
|
+
"""Converts all Path objects stored inside the class to strings.
|
|
152
|
+
|
|
153
|
+
This transformation is required to support dumping class data into a .YAML file so that the data can be stored
|
|
154
|
+
on disk.
|
|
155
|
+
"""
|
|
156
|
+
def make_dirs(self) -> None:
|
|
157
|
+
"""Ensures that all major subdirectories and the root raw_data directory exist.
|
|
158
|
+
|
|
159
|
+
This method is used by the VRPC to generate the raw_data directory when it creates a new session.
|
|
160
|
+
"""
|
|
161
|
+
def switch_root(self, new_root: Path) -> None:
|
|
162
|
+
"""Changes the root of the managed raw_data directory to the provided root path.
|
|
163
|
+
|
|
164
|
+
This service method is used by the SessionData class to convert all paths in this class to be relative to the
|
|
165
|
+
new root. This is used to adjust the SessionData instance to work for the VRPC (one root) or the BioHPC server
|
|
166
|
+
(another root). This method is only implemented for subclasses intended to be used both locally and on the
|
|
167
|
+
BioHPC server.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
171
|
+
root session directory: pc_root/project/animal/session.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
@dataclass()
|
|
175
|
+
class ProcessedData:
|
|
176
|
+
"""Stores the paths to the directories and files that make up the 'processed_data' session directory.
|
|
177
|
+
|
|
178
|
+
The processed_data directory stores the processed session data, which is generated by running various processing
|
|
179
|
+
pipelines. These pipelines use raw data to generate processed data, which represents an intermediate step between
|
|
180
|
+
raw data and the dataset used in the data analysis.
|
|
181
|
+
|
|
182
|
+
Notes:
|
|
183
|
+
The paths from this section are typically used only on the BioHPC server. This is because most data processing
|
|
184
|
+
in the lab is performed using the processing server's resources. On the server, processed data is stored on
|
|
185
|
+
the fast volume, in contrast to raw data, which is stored on the slow volume. However, to support local testing,
|
|
186
|
+
the class resolves the paths in this section both locally and globally (on the server).
|
|
187
|
+
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
processed_data_path: str | Path
|
|
191
|
+
camera_data_path: str | Path
|
|
192
|
+
mesoscope_data_path: str | Path
|
|
193
|
+
behavior_data_path: str | Path
|
|
194
|
+
deeplabcut_root_path: str | Path
|
|
195
|
+
suite2p_configuration_path: str | Path
|
|
196
|
+
def __post_init__(self) -> None:
|
|
197
|
+
"""This method is automatically called after class instantiation and ensures that all path fields of the class
|
|
198
|
+
are converted to Path objects.
|
|
199
|
+
"""
|
|
200
|
+
def make_string(self) -> None:
|
|
201
|
+
"""Converts all Path objects stored inside the class to strings.
|
|
202
|
+
|
|
203
|
+
This transformation is required to support dumping class data into a .YAML file so that the data can be stored
|
|
204
|
+
on disk.
|
|
205
|
+
"""
|
|
206
|
+
def make_dirs(self) -> None:
|
|
207
|
+
"""Ensures that all major subdirectories of the processed_data directory exist.
|
|
208
|
+
|
|
209
|
+
This method is used by the BioHPC server to generate the processed_data directory as part of the sl-forgery
|
|
210
|
+
library runtime.
|
|
211
|
+
"""
|
|
212
|
+
def switch_root(self, new_root: Path) -> None:
|
|
213
|
+
"""Changes the root of the managed processed_data directory to the provided root path.
|
|
214
|
+
|
|
215
|
+
This service method is used by the SessionData class to convert all paths in this class to be relative to the
|
|
216
|
+
new root. This is used to adjust the SessionData instance to work for the VRPC (one root) or the BioHPC server
|
|
217
|
+
(another root). This method is only implemented for subclasses intended to be used both locally and on the
|
|
218
|
+
BioHPC server.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
new_root: The new root directory to use for all paths inside the instance. This has to be the path to the
|
|
222
|
+
root session directory: pc_root/project/animal/session.
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
@dataclass()
|
|
226
|
+
class PersistentData:
|
|
227
|
+
"""Stores the paths to the directories and files that make up the 'persistent_data' directories of the VRPC and
|
|
228
|
+
the ScanImagePC.
|
|
229
|
+
|
|
230
|
+
Persistent data directories are used to keep certain files on the VRPC and the ScanImagePC. Typically, this data
|
|
231
|
+
is reused during the following sessions. For example, a copy of Zaber motor positions is persisted on the VRPC for
|
|
232
|
+
each animal after every session to support automatically restoring Zaber motors to the positions used during the
|
|
233
|
+
previous session.
|
|
234
|
+
|
|
235
|
+
Notes:
|
|
236
|
+
Persistent data includes the project and experiment configuration data. Some persistent data is overwritten
|
|
237
|
+
after each session, other data is generated once and kept through the animal's lifetime. Primarily, this data is
|
|
238
|
+
only used internally by the sl-experiment or sl-forgery libraries and is not intended for end-users.
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
zaber_positions_path: str | Path
|
|
242
|
+
mesoscope_positions_path: str | Path
|
|
243
|
+
motion_estimator_path: str | Path
|
|
244
|
+
def __post_init__(self) -> None:
|
|
245
|
+
"""This method is automatically called after class instantiation and ensures that all path fields of the class
|
|
246
|
+
are converted to Path objects.
|
|
247
|
+
"""
|
|
248
|
+
def make_string(self) -> None:
|
|
249
|
+
"""Converts all Path objects stored inside the class to strings.
|
|
250
|
+
|
|
251
|
+
This transformation is required to support dumping class data into a .YAML file so that the data can be stored
|
|
252
|
+
on disk.
|
|
253
|
+
"""
|
|
254
|
+
def make_dirs(self) -> None:
|
|
255
|
+
"""Ensures that the VRPC and the ScanImagePC persistent_data directories exist."""
|
|
256
|
+
|
|
257
|
+
@dataclass()
|
|
258
|
+
class MesoscopeData:
|
|
259
|
+
"""Stores the paths to the directories used by the ScanImagePC to save mesoscope-generated data during session
|
|
260
|
+
runtime.
|
|
261
|
+
|
|
262
|
+
The ScanImagePC is largely isolated from the VRPC during runtime. For the VRPC to pull the data acquired by the
|
|
263
|
+
ScanImagePC, it has to use the predefined directory structure to save the data. This class stores the predefined
|
|
264
|
+
path to various directories where ScanImagePC is expected to save the data and store it after acquisition.sers.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
root_data_path: str | Path
|
|
268
|
+
mesoscope_data_path: str | Path
|
|
269
|
+
session_specific_mesoscope_data_path: str | Path
|
|
270
|
+
def __post_init__(self) -> None:
|
|
271
|
+
"""This method is automatically called after class instantiation and ensures that all path fields of the class
|
|
272
|
+
are converted to Path objects.
|
|
273
|
+
"""
|
|
274
|
+
def make_string(self) -> None:
|
|
275
|
+
"""Converts all Path objects stored inside the class to strings.
|
|
276
|
+
|
|
277
|
+
This transformation is required to support dumping class data into a .YAML file so that the data can be stored
|
|
278
|
+
on disk.
|
|
279
|
+
"""
|
|
280
|
+
def make_dirs(self) -> None:
|
|
281
|
+
"""Ensures that the ScanImagePC data acquisition directories exist."""
|
|
282
|
+
|
|
283
|
+
@dataclass()
|
|
284
|
+
class Destinations:
|
|
285
|
+
"""Stores the paths to the VRPC filesystem-mounted Synology NAS and BioHPC server directories.
|
|
286
|
+
|
|
287
|
+
These directories are used during data preprocessing to transfer the preprocessed raw_data directory from the
|
|
288
|
+
VRPC to the long-term storage destinations.
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
nas_raw_data_path: str | Path
|
|
292
|
+
server_raw_data_path: str | Path
|
|
293
|
+
def __post_init__(self) -> None:
|
|
294
|
+
"""This method is automatically called after class instantiation and ensures that all path fields of the class
|
|
295
|
+
are converted to Path objects.
|
|
296
|
+
"""
|
|
297
|
+
def make_string(self) -> None:
|
|
298
|
+
"""Converts all Path objects stored inside the class to strings.
|
|
299
|
+
|
|
300
|
+
This transformation is required to support dumping class data into a .YAML file so that the data can be stored
|
|
301
|
+
on disk.
|
|
302
|
+
"""
|
|
303
|
+
def make_dirs(self) -> None:
|
|
304
|
+
"""Ensures that all destination directories exist."""
|
|
305
|
+
|
|
306
|
+
@dataclass
|
|
307
|
+
class SessionData(YamlConfig):
|
|
308
|
+
"""Provides methods for managing the data of a single experiment or training session across all destinations.
|
|
309
|
+
|
|
310
|
+
The primary purpose of this class is to maintain the session data structure across all supported destinations. It
|
|
311
|
+
generates the paths used by all other classes from this library and classes from sl-experiment and sl-forgery
|
|
312
|
+
libraries.
|
|
313
|
+
|
|
314
|
+
If necessary, the class can be used to either generate a new session or to load an already existing session's data.
|
|
315
|
+
When the class is used to create a new session, it automatically resolves the new session's name using the current
|
|
316
|
+
UTC timestamp, down to microseconds. This ensures that each session name is unique and preserves the overall
|
|
317
|
+
session order.
|
|
318
|
+
|
|
319
|
+
Notes:
|
|
320
|
+
If this class is instantiated on the VRPC, it is expected that the BioHPC server, Synology NAS, and ScanImagePC
|
|
321
|
+
data directories are mounted on the local host-machine via the SMB or equivalent protocol. All manipulations
|
|
322
|
+
with these destinations are carried out with the assumption that the OS has full access to these directories
|
|
323
|
+
and filesystems.
|
|
324
|
+
|
|
325
|
+
If this class is instantiated on the BioHPC server, some methods from this class will not work as expected. It
|
|
326
|
+
is essential that this class is not used outside the default sl-experiment and sl-forgery library runtimes to
|
|
327
|
+
ensure it is used safely.
|
|
328
|
+
|
|
329
|
+
This class is specifically designed for working with the data from a single session, performed by a single
|
|
330
|
+
animal under the specific experiment. The class is used to manage both raw and processed data. It follows the
|
|
331
|
+
data through acquisition, preprocessing and processing stages of the Sun lab data workflow.
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
project_name: str
|
|
335
|
+
animal_id: str
|
|
336
|
+
session_name: str
|
|
337
|
+
session_type: str
|
|
338
|
+
experiment_name: str | None
|
|
339
|
+
raw_data: RawData
|
|
340
|
+
processed_data: ProcessedData
|
|
341
|
+
persistent_data: PersistentData
|
|
342
|
+
mesoscope_data: MesoscopeData
|
|
343
|
+
destinations: Destinations
|
|
344
|
+
@classmethod
|
|
345
|
+
def create_session(
|
|
346
|
+
cls,
|
|
347
|
+
animal_id: str,
|
|
348
|
+
session_type: str,
|
|
349
|
+
project_configuration: ProjectConfiguration,
|
|
350
|
+
experiment_name: str | None = None,
|
|
351
|
+
) -> SessionData:
|
|
352
|
+
"""Creates a new SessionData object and uses it to generate the session's data structure.
|
|
353
|
+
|
|
354
|
+
This method is used to initialize new session runtimes. It always assumes it is called on the VRPC and, as part
|
|
355
|
+
of its runtime, resolves and generates the necessary local and ScanImagePC directories to support acquiring and
|
|
356
|
+
preprocessing session's data.
|
|
357
|
+
|
|
358
|
+
Notes:
|
|
359
|
+
To load an already existing session data structure, use the load_session() method instead.
|
|
360
|
+
|
|
361
|
+
This method automatically dumps the data of the created SessionData instance into the session_data.yaml file
|
|
362
|
+
inside the root raw_data directory of the created hierarchy. It also finds and dumps other configuration
|
|
363
|
+
files, such as project_configuration.yaml, suite2p_configuration.yaml, and experiment_configuration.yaml.
|
|
364
|
+
This way, if the session's runtime is interrupted unexpectedly, it can still be processed.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
animal_id: The ID code of the animal for which the data is acquired.
|
|
368
|
+
session_type: The type of the session. Primarily, this determines how to read the session_descriptor.yaml
|
|
369
|
+
file. Valid options are 'Lick training', 'Run training', or 'Experiment'.
|
|
370
|
+
experiment_name: The name of the experiment to be executed as part of this session. This option is only used
|
|
371
|
+
for 'Experiment' session types. It is used to find the target experiment configuration .YAML file and
|
|
372
|
+
copy it into the session's raw_data directory.
|
|
373
|
+
project_configuration: The initialized ProjectConfiguration instance that stores the data for the session's
|
|
374
|
+
project. This is used to determine the root directory paths for all PCs used in the data workflow.
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
An initialized SessionData instance for the newly created session.
|
|
378
|
+
"""
|
|
379
|
+
@classmethod
|
|
380
|
+
def load_session(cls, session_path: Path, on_server: bool) -> SessionData:
|
|
381
|
+
"""Loads the SessionData instance from the session_data.yaml file of the target session.
|
|
382
|
+
|
|
383
|
+
This method is used to load the data for an already existing session. This is used to call preprocessing
|
|
384
|
+
or processing runtime(s) for the target session. Depending on the call location, the method automatically
|
|
385
|
+
resolves all necessary paths and creates the necessary directories.
|
|
386
|
+
|
|
387
|
+
Notes:
|
|
388
|
+
To create a new session, use the create_session() method instead.
|
|
389
|
+
|
|
390
|
+
Args:
|
|
391
|
+
session_path: The path to the root directory of an existing session, e.g.: vrpc_root/project/animal/session.
|
|
392
|
+
on_server: Determines whether the method is used to initialize an existing session on the VRPC or the
|
|
393
|
+
BioHPC server.
|
|
394
|
+
|
|
395
|
+
Returns:
|
|
396
|
+
An initialized SessionData instance for the session whose data is stored at the provided path.
|
|
397
|
+
|
|
398
|
+
Raises:
|
|
399
|
+
FileNotFoundError: If the 'session_data.yaml' file is not found after resolving the provided path.
|
|
400
|
+
"""
|
|
401
|
+
def _to_path(self) -> None:
|
|
402
|
+
"""Saves the instance data to the 'raw_data' directory of the managed session as a 'session_data.yaml' file.
|
|
403
|
+
|
|
404
|
+
This is used to save the data stored in the instance to disk, so that it can be reused during preprocessing or
|
|
405
|
+
data processing. The method is intended to only be used by the SessionData instance itself during its
|
|
406
|
+
create_session() method runtime.
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
@dataclass()
|
|
410
|
+
class ExperimentState:
|
|
411
|
+
"""Encapsulates the information used to set and maintain the desired experiment and Mesoscope-VR system state.
|
|
412
|
+
|
|
413
|
+
Primarily, experiment runtime logic (task logic) is resolved by the Unity game engine. However, the Mesoscope-VR
|
|
414
|
+
system configuration may also need to change throughout the experiment to optimize the runtime by disabling or
|
|
415
|
+
reconfiguring specific hardware modules. For example, some experiment stages may require the running wheel to be
|
|
416
|
+
locked to prevent the animal from running, and other may require the VR screens to be turned off.
|
|
417
|
+
"""
|
|
418
|
+
|
|
419
|
+
experiment_state_code: int
|
|
420
|
+
vr_state_code: int
|
|
421
|
+
state_duration_s: float
|
|
422
|
+
|
|
423
|
+
@dataclass()
|
|
424
|
+
class ExperimentConfiguration(YamlConfig):
|
|
425
|
+
"""Stores the configuration of a single experiment runtime.
|
|
426
|
+
|
|
427
|
+
Primarily, this includes the sequence of experiment and Virtual Reality (Mesoscope-VR) states that defines the flow
|
|
428
|
+
of the experiment runtime. During runtime, the main runtime control function traverses the sequence of states
|
|
429
|
+
stored in this class instance start-to-end in the exact order specified by the user. Together with custom Unity
|
|
430
|
+
projects that define the task logic (how the system responds to animal interactions with the VR system) this class
|
|
431
|
+
allows flexibly implementing a wide range of experiments.
|
|
432
|
+
|
|
433
|
+
Each project should define one or more experiment configurations and save them as .yaml files inside the project
|
|
434
|
+
'configuration' folder. The name for each configuration file is defined by the user and is used to identify and load
|
|
435
|
+
the experiment configuration when 'sl-run-experiment' CLI command exposed by the sl-experiment library is executed.
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
cue_map: dict[int, float] = field(default_factory=Incomplete)
|
|
439
|
+
experiment_states: dict[str, ExperimentState] = field(default_factory=Incomplete)
|
|
440
|
+
|
|
441
|
+
@dataclass()
|
|
442
|
+
class HardwareConfiguration(YamlConfig):
|
|
443
|
+
"""This class is used to save the runtime hardware configuration parameters as a .yaml file.
|
|
444
|
+
|
|
445
|
+
This information is used to read and decode the data saved to the .npz log files during runtime as part of data
|
|
446
|
+
processing.
|
|
447
|
+
|
|
448
|
+
Notes:
|
|
449
|
+
All fields in this dataclass initialize to None. During log processing, any log associated with a hardware
|
|
450
|
+
module that provides the data stored in a field will be processed, unless that field is None. Therefore, setting
|
|
451
|
+
any field in this dataclass to None also functions as a flag for whether to parse the log associated with the
|
|
452
|
+
module that provides this field's information.
|
|
453
|
+
|
|
454
|
+
This class is automatically configured by MesoscopeExperiment and BehaviorTraining classes from sl-experiment
|
|
455
|
+
library to facilitate log parsing.
|
|
456
|
+
"""
|
|
457
|
+
|
|
458
|
+
cue_map: dict[int, float] | None = ...
|
|
459
|
+
cm_per_pulse: float | None = ...
|
|
460
|
+
maximum_break_strength: float | None = ...
|
|
461
|
+
minimum_break_strength: float | None = ...
|
|
462
|
+
lick_threshold: int | None = ...
|
|
463
|
+
valve_scale_coefficient: float | None = ...
|
|
464
|
+
valve_nonlinearity_exponent: float | None = ...
|
|
465
|
+
torque_per_adc_unit: float | None = ...
|
|
466
|
+
screens_initially_on: bool | None = ...
|
|
467
|
+
recorded_mesoscope_ttl: bool | None = ...
|
|
468
|
+
|
|
469
|
+
@dataclass()
|
|
470
|
+
class LickTrainingDescriptor(YamlConfig):
|
|
471
|
+
"""This class is used to save the description information specific to lick training sessions as a .yaml file.
|
|
472
|
+
|
|
473
|
+
The information stored in this class instance is filled in two steps. The main runtime function fills most fields
|
|
474
|
+
of the class, before it is saved as a .yaml file. After runtime, the experimenter manually fills leftover fields,
|
|
475
|
+
such as 'experimenter_notes,' before the class instance is transferred to the long-term storage destination.
|
|
476
|
+
|
|
477
|
+
The fully filled instance data is also used during preprocessing to write the water restriction log entry for the
|
|
478
|
+
trained animal.
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
experimenter: str
|
|
482
|
+
mouse_weight_g: float
|
|
483
|
+
dispensed_water_volume_ml: float
|
|
484
|
+
minimum_reward_delay: int
|
|
485
|
+
maximum_reward_delay_s: int
|
|
486
|
+
maximum_water_volume_ml: float
|
|
487
|
+
maximum_training_time_m: int
|
|
488
|
+
experimenter_notes: str = ...
|
|
489
|
+
experimenter_given_water_volume_ml: float = ...
|
|
490
|
+
|
|
491
|
+
@dataclass()
|
|
492
|
+
class RunTrainingDescriptor(YamlConfig):
|
|
493
|
+
"""This class is used to save the description information specific to run training sessions as a .yaml file.
|
|
494
|
+
|
|
495
|
+
The information stored in this class instance is filled in two steps. The main runtime function fills most fields
|
|
496
|
+
of the class, before it is saved as a .yaml file. After runtime, the experimenter manually fills leftover fields,
|
|
497
|
+
such as 'experimenter_notes,' before the class instance is transferred to the long-term storage destination.
|
|
498
|
+
|
|
499
|
+
The fully filled instance data is also used during preprocessing to write the water restriction log entry for the
|
|
500
|
+
trained animal.
|
|
501
|
+
"""
|
|
502
|
+
|
|
503
|
+
experimenter: str
|
|
504
|
+
mouse_weight_g: float
|
|
505
|
+
dispensed_water_volume_ml: float
|
|
506
|
+
final_run_speed_threshold_cm_s: float
|
|
507
|
+
final_run_duration_threshold_s: float
|
|
508
|
+
initial_run_speed_threshold_cm_s: float
|
|
509
|
+
initial_run_duration_threshold_s: float
|
|
510
|
+
increase_threshold_ml: float
|
|
511
|
+
run_speed_increase_step_cm_s: float
|
|
512
|
+
run_duration_increase_step_s: float
|
|
513
|
+
maximum_water_volume_ml: float
|
|
514
|
+
maximum_training_time_m: int
|
|
515
|
+
experimenter_notes: str = ...
|
|
516
|
+
experimenter_given_water_volume_ml: float = ...
|
|
517
|
+
|
|
518
|
+
@dataclass()
|
|
519
|
+
class MesoscopeExperimentDescriptor(YamlConfig):
|
|
520
|
+
"""This class is used to save the description information specific to experiment sessions as a .yaml file.
|
|
521
|
+
|
|
522
|
+
The information stored in this class instance is filled in two steps. The main runtime function fills most fields
|
|
523
|
+
of the class, before it is saved as a .yaml file. After runtime, the experimenter manually fills leftover fields,
|
|
524
|
+
such as 'experimenter_notes,' before the class instance is transferred to the long-term storage destination.
|
|
525
|
+
|
|
526
|
+
The fully filled instance data is also used during preprocessing to write the water restriction log entry for the
|
|
527
|
+
animal participating in the experiment runtime.
|
|
528
|
+
"""
|
|
529
|
+
|
|
530
|
+
experimenter: str
|
|
531
|
+
mouse_weight_g: float
|
|
532
|
+
dispensed_water_volume_ml: float
|
|
533
|
+
experimenter_notes: str = ...
|
|
534
|
+
experimenter_given_water_volume_ml: float = ...
|
|
535
|
+
|
|
536
|
+
@dataclass()
|
|
537
|
+
class ZaberPositions(YamlConfig):
|
|
538
|
+
"""This class is used to save Zaber motor positions as a .yaml file to reuse them between sessions.
|
|
539
|
+
|
|
540
|
+
The class is specifically designed to store, save, and load the positions of the LickPort and HeadBar motors
|
|
541
|
+
(axes). It is used to both store Zaber motor positions for each session for future analysis and to restore the same
|
|
542
|
+
Zaber motor positions across consecutive runtimes for the same project and animal combination.
|
|
543
|
+
|
|
544
|
+
Notes:
|
|
545
|
+
All positions are saved using native motor units. All class fields initialize to default placeholders that are
|
|
546
|
+
likely NOT safe to apply to the VR system. Do not apply the positions loaded from the file unless you are
|
|
547
|
+
certain they are safe to use.
|
|
548
|
+
|
|
549
|
+
Exercise caution when working with Zaber motors. The motors are powerful enough to damage the surrounding
|
|
550
|
+
equipment and manipulated objects. Do not modify the data stored inside the .yaml file unless you know what you
|
|
551
|
+
are doing.
|
|
552
|
+
"""
|
|
553
|
+
|
|
554
|
+
headbar_z: int = ...
|
|
555
|
+
headbar_pitch: int = ...
|
|
556
|
+
headbar_roll: int = ...
|
|
557
|
+
lickport_z: int = ...
|
|
558
|
+
lickport_x: int = ...
|
|
559
|
+
lickport_y: int = ...
|
|
560
|
+
|
|
561
|
+
@dataclass()
|
|
562
|
+
class MesoscopePositions(YamlConfig):
|
|
563
|
+
"""This class is used to save the real and virtual Mesoscope objective positions as a .yaml file to reuse it
|
|
564
|
+
between experiment sessions.
|
|
565
|
+
|
|
566
|
+
Primarily, the class is used to help the experimenter to position the Mesoscope at the same position across
|
|
567
|
+
multiple imaging sessions. It stores both the physical (real) position of the objective along the motorized
|
|
568
|
+
X, Y, Z, and Roll axes and the virtual (ScanImage software) tip, tilt, and fastZ focus axes.
|
|
569
|
+
|
|
570
|
+
Notes:
|
|
571
|
+
Since the API to read and write these positions automatically is currently not available, this class relies on
|
|
572
|
+
the experimenter manually entering all positions and setting the mesoscope to these positions when necessary.
|
|
573
|
+
"""
|
|
574
|
+
|
|
575
|
+
mesoscope_x_position: float = ...
|
|
576
|
+
mesoscope_y_position: float = ...
|
|
577
|
+
mesoscope_roll_position: float = ...
|
|
578
|
+
mesoscope_z_position: float = ...
|
|
579
|
+
mesoscope_fast_z_position: float = ...
|
|
580
|
+
mesoscope_tip_position: float = ...
|
|
581
|
+
mesoscope_tilt_position: float = ...
|
|
582
|
+
|
|
583
|
+
@dataclass()
|
|
584
|
+
class SubjectData:
|
|
585
|
+
"""Stores the ID information of the surgical intervention's subject (animal)."""
|
|
586
|
+
|
|
587
|
+
id: int
|
|
588
|
+
ear_punch: str
|
|
589
|
+
sex: str
|
|
590
|
+
genotype: str
|
|
591
|
+
date_of_birth_us: int
|
|
592
|
+
weight_g: float
|
|
593
|
+
cage: int
|
|
594
|
+
location_housed: str
|
|
595
|
+
status: str
|
|
596
|
+
|
|
597
|
+
@dataclass()
|
|
598
|
+
class ProcedureData:
|
|
599
|
+
"""Stores the general information about the surgical intervention."""
|
|
600
|
+
|
|
601
|
+
surgery_start_us: int
|
|
602
|
+
surgery_end_us: int
|
|
603
|
+
surgeon: str
|
|
604
|
+
protocol: str
|
|
605
|
+
surgery_notes: str
|
|
606
|
+
post_op_notes: str
|
|
607
|
+
|
|
608
|
+
@dataclass
|
|
609
|
+
class ImplantData:
|
|
610
|
+
"""Stores the information about a single implantation performed during the surgical intervention.
|
|
611
|
+
|
|
612
|
+
Multiple ImplantData instances are used at the same time if the surgery involved multiple implants.
|
|
613
|
+
"""
|
|
614
|
+
|
|
615
|
+
implant: str
|
|
616
|
+
implant_target: str
|
|
617
|
+
implant_code: int
|
|
618
|
+
implant_ap_coordinate_mm: float
|
|
619
|
+
implant_ml_coordinate_mm: float
|
|
620
|
+
implant_dv_coordinate_mm: float
|
|
621
|
+
|
|
622
|
+
@dataclass
|
|
623
|
+
class InjectionData:
|
|
624
|
+
"""Stores the information about a single injection performed during surgical intervention.
|
|
625
|
+
|
|
626
|
+
Multiple InjectionData instances are used at the same time if the surgery involved multiple injections.
|
|
627
|
+
"""
|
|
628
|
+
|
|
629
|
+
injection: str
|
|
630
|
+
injection_target: str
|
|
631
|
+
injection_volume_nl: float
|
|
632
|
+
injection_code: int
|
|
633
|
+
injection_ap_coordinate_mm: float
|
|
634
|
+
injection_ml_coordinate_mm: float
|
|
635
|
+
injection_dv_coordinate_mm: float
|
|
636
|
+
|
|
637
|
+
@dataclass
|
|
638
|
+
class DrugData:
|
|
639
|
+
"""Stores the information about all drugs administered to the subject before, during, and immediately after the
|
|
640
|
+
surgical intervention.
|
|
641
|
+
"""
|
|
642
|
+
|
|
643
|
+
lactated_ringers_solution_volume_ml: float
|
|
644
|
+
lactated_ringers_solution_code: int
|
|
645
|
+
ketoprofen_volume_ml: float
|
|
646
|
+
ketoprofen_code: int
|
|
647
|
+
buprenorphine_volume_ml: float
|
|
648
|
+
buprenorphine_code: int
|
|
649
|
+
dexamethasone_volume_ml: float
|
|
650
|
+
dexamethasone_code: int
|
|
651
|
+
|
|
652
|
+
@dataclass
|
|
653
|
+
class SurgeryData(YamlConfig):
|
|
654
|
+
"""Stores the data about a single mouse surgical intervention.
|
|
655
|
+
|
|
656
|
+
This class aggregates other dataclass instances that store specific data about the surgical procedure. Primarily, it
|
|
657
|
+
is used to save the data as a .yaml file to every session's raw_data directory of each animal used in every lab
|
|
658
|
+
project. This way, the surgery data is always stored alongside the behavior and brain activity data collected
|
|
659
|
+
during the session.
|
|
660
|
+
"""
|
|
661
|
+
|
|
662
|
+
subject: SubjectData
|
|
663
|
+
procedure: ProcedureData
|
|
664
|
+
drugs: DrugData
|
|
665
|
+
implants: list[ImplantData]
|
|
666
|
+
injections: list[InjectionData]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sl-shared-assets
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0rc6
|
|
4
4
|
Summary: Stores assets shared between multiple Sun (NeuroAI) lab data pipelines.
|
|
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/
|
|
@@ -2,7 +2,8 @@ sl_shared_assets/__init__.py,sha256=V7EvTTSB_GhetCbyYPg2RoiG1etDVeML5EBWgGvUo7E,
|
|
|
2
2
|
sl_shared_assets/__init__.pyi,sha256=U5Sma4zenITe0-eI_heTUYh_9P0puhgM3hAdcf-qozk,2532
|
|
3
3
|
sl_shared_assets/cli.py,sha256=CjfuXXj7CeDA2pbCwe5Rad6RDjIqGDud14IUDMdzx_w,2639
|
|
4
4
|
sl_shared_assets/cli.pyi,sha256=X5UdXpkzUw71_ftaIXMsnttIeR15SPVLiECuPge_zw8,1032
|
|
5
|
-
sl_shared_assets/data_classes.py,sha256=
|
|
5
|
+
sl_shared_assets/data_classes.py,sha256=JOSaK1aaAvpQe9LzqXNfBF-MRtORt1p8tTltlDrnS7k,86614
|
|
6
|
+
sl_shared_assets/data_classes.pyi,sha256=b42VCMyRJIiOpRQHCfgaZYcH91xgm1ymzHfA3N4vY88,32209
|
|
6
7
|
sl_shared_assets/packaging_tools.py,sha256=3kAXFK37Lv4JA1YhjcoBz1x2Ell8ObCqe9pwxAts4m4,6709
|
|
7
8
|
sl_shared_assets/packaging_tools.pyi,sha256=hlAP9AxF7NHtFIPKjj5ehm8Vr9qIn6xDk4VvL0JuAmk,3055
|
|
8
9
|
sl_shared_assets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -12,8 +13,8 @@ sl_shared_assets/suite2p.py,sha256=sQ5Zj0TJFD-gUHqtWnRvapBpr8QgmaiVil123cWxGxc,2
|
|
|
12
13
|
sl_shared_assets/suite2p.pyi,sha256=Uyv8ov--etwJIc6e2UVgs0jYXwnK2CD-kICfXo5KpcI,6331
|
|
13
14
|
sl_shared_assets/transfer_tools.py,sha256=J26kwOp_NpPSY0-xu5FTw9udte-rm_mW1FJyaTNoqQI,6606
|
|
14
15
|
sl_shared_assets/transfer_tools.pyi,sha256=FoH7eYZe7guGHfPr0MK5ggO62uXKwD2aJ7h1Bu7PaEE,3294
|
|
15
|
-
sl_shared_assets-1.0.
|
|
16
|
-
sl_shared_assets-1.0.
|
|
17
|
-
sl_shared_assets-1.0.
|
|
18
|
-
sl_shared_assets-1.0.
|
|
19
|
-
sl_shared_assets-1.0.
|
|
16
|
+
sl_shared_assets-1.0.0rc6.dist-info/METADATA,sha256=HKC5KfyBloEjbXve5EPtwKtq-tMwHmx8U8ABZ1ux6DI,47806
|
|
17
|
+
sl_shared_assets-1.0.0rc6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
18
|
+
sl_shared_assets-1.0.0rc6.dist-info/entry_points.txt,sha256=3VPr5RkWBkusNN9OhWXtC-DN0utu7uMrUulazIK2VNA,166
|
|
19
|
+
sl_shared_assets-1.0.0rc6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
20
|
+
sl_shared_assets-1.0.0rc6.dist-info/RECORD,,
|
|
File without changes
|
{sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{sl_shared_assets-1.0.0rc4.dist-info → sl_shared_assets-1.0.0rc6.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|