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.

@@ -1,6 +1,7 @@
1
- """This module provides classes used to store various data used by the sl-experiment and the sl-forgery libraries.
2
- This includes classes used to store the data generated during acquisition and preprocessing and classes used to manage
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
- import copy
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
- When ProjectConfiguration class is instantiated for the first time on a new machine, it asks the user to provide
23
- the path to the local directory where to save all Sun lab projects. This path is then stored inside the default
24
- user data directory as a .yaml file to be reused for all future projects. To support replacing this path without
25
- searching for the user data directory, which is usually hidden, this function finds and updates the contents of the
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
- This class allows flexibly configuring sl_experiment and sl_forgery libraries for different projects in the
57
- Sun lab. This allows hiding most inner workings of all libraries from the end-users, while providing a robust,
58
- machine-independent way to interface with all data acquisition and processing libraries.
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
- Most lab projects only need to adjust the "surgery_sheet_id" and "water_log_sheet_id" fields of the class.
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 surgery information for the animal whose data is managed by this
68
- instance. This is used to parse and write the surgery data for each managed animal into its 'metadata' folder, so
69
- that the surgery data is always kept together with the rest of the training and experiment data."""
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 water restriction information for the animal whose data is managed
72
- by this instance. This is used to synchronize the information inside the water restriction log with the state of
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. Usually, the
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 storage (filesystem) of the server machine should already be mounted to the local PC via SMB, this data
85
- is used to establish SSH connection to the machine and start data processing after it is transferred to the server.
86
- This way, our data acquisition, preprocessing, and processing are controlled by the same runtime.
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 root directory where all projects are stored on the local host-machine (VRPC). Note,
90
- overwriting the value of this field is pointless, as it is automatically set each time the class is instantiated."""
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 locally-mapped (via SMB protocol) root BioHPC server machine directory where to store
93
- all projects."""
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 locally-mapped (via SMB protocol) root Synology NAS directory where to store all
96
- projects."""
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 locally-mapped (via SMB protocol) root mesoscope (ScanImagePC) directory where all
99
- mesoscope-acquired data is aggregated during runtime."""
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. Currently, this is only used by
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. Note, this is only used during
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. Note, this is only used during
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 dictionary or tuple of tuples that maps valve open times, in microseconds, to the dispensed volume of water,
140
- in microliters. During runtime, this data is used by the ValveModule to translate the requested reward volumes into
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 and uses the loaded data
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 for each session runtime to reuse the configuration parameters generated at project
150
- creation. When it is called for the first time (during new project creation), the method generates the default
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 local data hierarchy.
156
- The path to the directory will be saved inside user's default data directory, so that it can be reused for
157
- all future projects. Use sl-replace_root_path CLI to replace the path that is saved in this way.
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 during both data acquisition and processing on different machines, this method
160
- supports multiple ways of initializing the class. Use the project_name on the VRPC (via the sl_experiment
161
- library). Use the configuration path on the BioHPC server (via the sl_forgery library).
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. Note, this
165
- way of resolving the project is the default way on the VRPC. When processing data on the server, the
166
- pipeline preferentially uses the configuration_path.
167
- configuration_path: The path to the project_configuration.yaml file from which to load the data. This is
168
- an optional way of resolving the configuration data source that always takes precedence over the
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
- An initialized ProjectConfiguration instance.
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._to_path(path=configuration_path)
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 _to_path(self, path: Path) -> None:
267
- """Saves the instance data to disk as a project_configuration.yaml file.
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 the project is created. All future runtimes should use the load()
270
- method to load and reuse the configuration data saved to the .yaml file.
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
- This method also generates and dumps multiple other 'precursor' configuration files into the folder. This
274
- includes the example 'default' experiment configuration and the DeepLabCut and Suite2P configuration files
275
- used during data processing.
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
- example_experiment = ExperimentConfiguration()
305
- example_experiment.to_yaml(path.parent.joinpath("default_experiment.yaml"))
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 to ensure its validity.
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 library. This internal method is automatically called by the load() method.
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 .tif files (brain activity data) and the motion estimation data."""
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
- root session directory: pc_root/project/animal/session.
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[2]
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 processed session data, which is generated by running various processing
498
- pipelines. These pipelines use raw data to generate processed data, which represents an intermediate step between
499
- raw data and the dataset used in the data analysis.
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
- root session directory: pc_root/project/animal/session.
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[2]
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
- """Provides methods for managing the data of a single experiment or training session across all destinations.
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. It
736
- generates the paths used by all other classes from this library and classes from sl-experiment and sl-forgery
737
- libraries.
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
- If necessary, the class can be used to either generate a new session or to load an already existing session's data.
740
- When the class is used to create a new session, it automatically resolves the new session's name using the current
741
- UTC timestamp, down to microseconds. This ensures that each session name is unique and preserves the overall
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 host-machine via the SMB or equivalent protocol. All manipulations
747
- with these destinations are carried out with the assumption that the OS has full access to these directories
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', this
771
- field is used to communicate the specific experiment configuration used by the session. During runtime, this is
772
- used to load the experiment configuration (to run the experiment) and to save the experiment configuration to the
773
- session raw_data folder. If the session is not an experiment session, this is statically set to None."""
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
- """Stores the paths to various directories and files used to store raw and preprocessed session data. Depending on
776
- class initialization location (VRPC or BioHPC server), the class automatically resolves the root directory path to
777
- either the VRPC project directory or the BioHPC cluster storage volume."""
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
- """Stores the paths to various directories used to store processed session data. Note, when this section is
780
- resolved for VRPC, it uses the same local session directory as the raw_data folder. When this is resolved for the
781
- BioHPC server, it uses the 'fast' volume path."""
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
- """Stores the paths to various files and directories kept on VRPC and ScanImagePC after the session data is
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
- """Stores the paths to various directories used by the ScanImagePC to store mesoscope-acquired session data,
787
- before it is moved to the VRPC during preprocessing."""
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
- """Stores the paths to the destination directories on the BioHPC server and Synology NAS, to which the data is
790
- copied as part of preprocessing. Both of these directories should be accessible for the VRPC's filesystem via an
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 create_session(
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 uses it to generate the session's data structure.
827
+ """Creates a new SessionData object and generates the new session's data structure.
802
828
 
803
- This method is used to initialize new session runtimes. It always assumes it is called on the VRPC and, as part
804
- of its runtime, resolves and generates the necessary local and ScanImagePC directories to support acquiring and
805
- preprocessing session's data.
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 load_session() method instead.
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, suite2p_configuration.yaml, and experiment_configuration.yaml.
813
- This way, if the session's runtime is interrupted unexpectedly, it can still be processed.
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 to be executed as part of this session. This option is only used
820
- for 'Experiment' session types. It is used to find the target experiment configuration .YAML file and
821
- copy it into the session's raw_data directory.
822
- project_configuration: The initialized ProjectConfiguration instance that stores the data for the session's
823
- project. This is used to determine the root directory paths for all PCs used in the data workflow.
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 for the newly created session.
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 = str(get_timestamp(time_separator="-"))
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._to_path()
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 load_session(
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 of the target session.
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 for an already existing session. This is used to call preprocessing
961
- or processing runtime(s) for the target session. Depending on the call location, the method automatically
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 create_session() method instead.
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 after resolving the provided path.
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=session_path) # type: ignore
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 _to_path(self) -> None:
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
- create_session() method runtime.
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