66"""
77
88import logging
9- import os
109from pathlib import Path
1110
1211import nwbinspector
1817from trodes_to_nwb .convert_dios import add_dios
1918from trodes_to_nwb .convert_ephys import RecFileDataChunkIterator , add_raw_ephys
2019from trodes_to_nwb .convert_intervals import add_epochs , add_sample_count
20+ from trodes_to_nwb .convert_optogenetics import add_optogenetic_epochs , add_optogenetics
2121from trodes_to_nwb .convert_position import add_associated_video_files , add_position
2222from trodes_to_nwb .convert_rec_header import (
2323 add_header_device ,
@@ -72,18 +72,16 @@ def setup_logger(name_logfile: str, path_logfile: str) -> logging.Logger:
7272 return logger
7373
7474
75- def get_included_probe_metadata_paths () -> list [Path ]:
75+ def get_included_device_metadata_paths () -> list [Path ]:
7676 """Get the included probe metadata paths
7777 Returns
7878 -------
79- probe_metadata_paths : list[Path]
79+ device_metadata_paths : list[Path]
8080 List of probe metadata paths
8181 """
8282 package_dir = Path (__file__ ).parent .resolve ()
83- probe_folder = package_dir / "probe_metadata"
84- return [
85- probe_folder / file for file in probe_folder .iterdir () if file .suffix == ".yml"
86- ]
83+ device_folder = package_dir / "device_metadata"
84+ return device_folder .rglob ("*.yml" )
8785
8886
8987def _get_file_paths (df : pd .DataFrame , file_extension : str ) -> list [str ]:
@@ -107,13 +105,15 @@ def _get_file_paths(df: pd.DataFrame, file_extension: str) -> list[str]:
107105def create_nwbs (
108106 path : Path ,
109107 header_reconfig_path : Path | None = None ,
110- probe_metadata_paths : list [Path ] | None = None ,
108+ device_metadata_paths : list [Path ] | None = None ,
111109 output_dir : str = "/stelmo/nwb/raw" ,
112110 video_directory : str = "" ,
113111 convert_video : bool = False ,
112+ fs_gui_dir : str = "" ,
114113 n_workers : int = 1 ,
115114 query_expression : str | None = None ,
116115 disable_ptp : bool = False ,
116+ behavior_only : bool = False ,
117117):
118118 """
119119 Convert SpikeGadgets data to NWB format.
@@ -124,14 +124,16 @@ def create_nwbs(
124124 Path to the SpikeGadgets data file.
125125 header_reconfig_path : Path, optional
126126 Path to the header reconfiguration file, by default None.
127- probe_metadata_paths : list[Path], optional
128- List of paths to the probe metadata files, by default None.
127+ device_metadata_paths : list[Path], optional
128+ List of paths to the device metadata files, by default None.
129129 output_dir : str, optional
130130 Output directory for the NWB files, by default "/stelmo/nwb/raw".
131131 video_directory : str, optional
132132 Directory containing the video files, by default "".
133133 convert_video : bool, optional
134134 Whether to convert the video files, by default False.
135+ fs_gui_dir : str, optional
136+ Optional alternative directory to find optogenetic files, by default "".
135137 n_workers : int, optional
136138 Number of workers to use for parallel processing, by default 1.
137139 query_expression : str, optional
@@ -140,15 +142,18 @@ def create_nwbs(
140142 See https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html.
141143 disable_ptp : bool, optional
142144 Blocks use of ptp timestamps regardless of rec header, by default False.
145+ behavior_only : bool, optional
146+ Flag to indicate only behaviorsl data (no ephys) was collected in the rec
147+ files, by default False.
143148
144149 """
145150
146151 if not isinstance (path , Path ):
147152 path = Path (path )
148153
149154 # provide the included probe metadata files if none are provided
150- if probe_metadata_paths is None :
151- probe_metadata_paths = get_included_probe_metadata_paths ()
155+ if device_metadata_paths is None :
156+ device_metadata_paths = get_included_device_metadata_paths ()
152157
153158 file_info = get_file_info (path )
154159
@@ -164,10 +169,13 @@ def pass_func(args):
164169 session ,
165170 session_df ,
166171 header_reconfig_path ,
167- probe_metadata_paths ,
172+ device_metadata_paths ,
168173 output_dir ,
169174 video_directory ,
170175 convert_video ,
176+ fs_gui_dir ,
177+ disable_ptp ,
178+ behavior_only = behavior_only ,
171179 )
172180 return True
173181 except Exception as e :
@@ -191,23 +199,27 @@ def pass_func(args):
191199 session ,
192200 session_df ,
193201 header_reconfig_path ,
194- probe_metadata_paths ,
202+ device_metadata_paths ,
195203 output_dir ,
196204 video_directory ,
197205 convert_video ,
206+ fs_gui_dir ,
198207 disable_ptp ,
208+ behavior_only = behavior_only ,
199209 )
200210
201211
202212def _create_nwb (
203213 session : tuple [str , str , str ],
204214 session_df : pd .DataFrame ,
205215 header_reconfig_path : Path | None = None ,
206- probe_metadata_paths : list [Path ] | None = None ,
216+ device_metadata_paths : list [Path ] | None = None ,
207217 output_dir : str = "/stelmo/nwb/raw" ,
208218 video_directory : str = "" ,
209219 convert_video : bool = False ,
220+ fs_gui_dir : str = "" ,
210221 disable_ptp : bool = False ,
222+ behavior_only : bool = False ,
211223):
212224 # create loggers
213225 logger = setup_logger ("convert" , f"{ session [1 ]} { session [0 ]} _convert.log" )
@@ -219,7 +231,10 @@ def _create_nwb(
219231 logger .info ("CREATING REC DATA ITERATORS" )
220232 # make generic rec file data chunk iterator to pass to functions
221233 rec_dci = RecFileDataChunkIterator (
222- rec_filepaths , interpolate_dropped_packets = False , stream_id = "trodes"
234+ rec_filepaths ,
235+ interpolate_dropped_packets = False ,
236+ stream_id = "ECU_analog" if behavior_only else "trodes" ,
237+ behavior_only = behavior_only ,
223238 )
224239 rec_dci_timestamps = (
225240 rec_dci .timestamps
@@ -241,8 +256,8 @@ def _create_nwb(
241256 metadata_filepaths = metadata_filepaths [0 ]
242257 logger .info (f"\t metadata_filepath: { metadata_filepaths } " )
243258
244- metadata , probe_metadata = load_metadata (
245- metadata_filepaths , probe_metadata_paths = probe_metadata_paths
259+ metadata , device_metadata = load_metadata (
260+ metadata_filepaths , device_metadata_paths = device_metadata_paths
246261 )
247262
248263 logger .info ("CREATING HARDWARE MAPS" )
@@ -265,29 +280,36 @@ def _create_nwb(
265280 add_acquisition_devices (nwb_file , metadata )
266281 add_tasks (nwb_file , metadata )
267282 add_associated_files (nwb_file , metadata )
268- add_electrode_groups (
269- nwb_file , metadata , probe_metadata , hw_channel_map , ref_electrode_map
270- )
271283 add_header_device (nwb_file , rec_header )
272284 add_associated_video_files (
273285 nwb_file , metadata , session_df , video_directory , convert_video
274286 )
287+ add_optogenetics (nwb_file , metadata , device_metadata )
275288
276- logger .info ("ADDING EPHYS DATA" )
277- ### add rec file data ###
278- map_row_ephys_data_to_row_electrodes_table = list (
279- range (len (nwb_file .electrodes ))
280- ) # TODO: Double check this
281- add_raw_ephys (
282- nwb_file ,
283- rec_filepaths ,
284- map_row_ephys_data_to_row_electrodes_table ,
285- metadata ,
286- )
289+ if not behavior_only :
290+ add_electrode_groups (
291+ nwb_file , metadata , device_metadata , hw_channel_map , ref_electrode_map
292+ )
293+ logger .info ("ADDING EPHYS DATA" )
294+ # add rec file data
295+ map_row_ephys_data_to_row_electrodes_table = list (
296+ range (len (nwb_file .electrodes ))
297+ ) # TODO: Double check this
298+ add_raw_ephys (
299+ nwb_file ,
300+ rec_filepaths ,
301+ map_row_ephys_data_to_row_electrodes_table ,
302+ metadata ,
303+ )
287304 logger .info ("ADDING DIO DATA" )
288305 add_dios (nwb_file , rec_filepaths , metadata )
289306 logger .info ("ADDING ANALOG DATA" )
290- add_analog_data (nwb_file , rec_filepaths , timestamps = rec_dci_timestamps )
307+ add_analog_data (
308+ nwb_file ,
309+ rec_filepaths ,
310+ timestamps = rec_dci_timestamps ,
311+ behavior_only = behavior_only ,
312+ )
291313 logger .info ("ADDING SAMPLE COUNTS" )
292314 add_sample_count (nwb_file , rec_dci )
293315 logger .info ("ADDING EPOCHS" )
@@ -296,8 +318,9 @@ def _create_nwb(
296318 session_df = session_df ,
297319 neo_io = rec_dci .neo_io ,
298320 )
321+ add_optogenetic_epochs (nwb_file , metadata , fs_gui_dir )
299322 logger .info ("ADDING POSITION" )
300- ### add position ###
323+ # add position
301324 if disable_ptp :
302325 ptp_enabled = False
303326 else :
0 commit comments