diff --git a/make_env.yml b/make_env.yml index fcf3f73..926a31e 100644 --- a/make_env.yml +++ b/make_env.yml @@ -6,4 +6,4 @@ dependencies: - python>=3.9 - pip - pip: - - -e . # This calls the setup and therefore requirements minimal + - -e . # This calls the setup and therefore pyproject.toml dependencies diff --git a/pyproject.toml b/pyproject.toml index 388eb56..d701271 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [project] name = "schneider-lab-to-nwb" -version = "0.0.1" +version = "0.1.0" description = "NWB conversion scripts, functions, and classes for Schneider conversion" readme = "README.md" -authors = [{ name = "CatalystNeuro", email = "ben.dichter@catalystneuro.com" }] -maintainers = [{ name = "CatalystNeuro", email = "ben.dichter@catalystneuro.com" }] +authors = [{ name = "CatalystNeuro", email = "paul.adkisson@catalystneuro.com" }] +maintainers = [{ name = "CatalystNeuro", email = "paul.adkisson@catalystneuro.com" }] license = { file = "LICENSE" } requires-python = ">=3.9" classifiers = [ @@ -17,6 +17,7 @@ classifiers = [ dependencies = [ "neuroconv", "nwbinspector", + "ndx-events==0.2.0" ] [project.urls] diff --git a/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_behaviorinterface.py b/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_behaviorinterface.py index 0c6a65f..739a5c5 100644 --- a/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_behaviorinterface.py +++ b/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_behaviorinterface.py @@ -6,7 +6,7 @@ from hdmf.common.table import DynamicTableRegion from pynwb.behavior import BehavioralTimeSeries, TimeSeries from pynwb.device import Device -from ndx_events import EventTypesTable, EventsTable, Task, TimestampVectorData +from ndx_events import Events, AnnotatedEventsTable from neuroconv.basedatainterface import BaseDataInterface from neuroconv.utils import DeepDict, get_base_schema @@ -158,28 +158,6 @@ def add_to_nwbfile( behavior_module.add(behavioral_time_series) # Add Events - event_types_table = EventTypesTable(name="event_types", description="Metadata about event types.") - event_type_name_to_row = dict() - i = 0 - for event_dict in metadata["Behavior"]["Events"]: - event_type_name_to_row[event_dict["name"]] = i - event_types_table.add_row( - event_name=event_dict["name"], - event_type_description=event_dict["description"], - ) - i += 1 - for event_dict in metadata["Behavior"]["ValuedEvents"]: - event_type_name_to_row[event_dict["name"]] = i - event_types_table.add_row( - event_name=event_dict["name"], - event_type_description=event_dict["description"], - ) - i += 1 - events_table = EventsTable( - name="events_table", - description="Metadata about events.", - target_tables={"event_type": event_types_table}, - ) for event_dict in metadata["Behavior"]["Events"]: event_times = name_to_times[event_dict["name"]] if np.all(np.isnan(event_times)): @@ -188,15 +166,18 @@ def add_to_nwbfile( f"An event provided in the metadata ({event_dict['name']}) will be skipped because no times were found." ) continue # Skip if all times are NaNs - event_type = event_type_name_to_row[event_dict["name"]] - for event_time in event_times: - events_table.add_row(timestamp=event_time, event_type=event_type) - valued_events_table = EventsTable( + event = Events( + name=event_dict["name"], + description=event_dict["description"], + timestamps=event_times, + ) + behavior_module.add(event) + + valued_events_table = AnnotatedEventsTable( name="valued_events_table", description="Metadata about valued events.", - target_tables={"event_type": event_types_table}, ) - valued_events_table.add_column(name="value", description="Value of the event.") + valued_events_table.add_column(name="value", description="Value of the event.", index=True) for event_dict in metadata["Behavior"]["ValuedEvents"]: event_times = name_to_times[event_dict["name"]] if np.all(np.isnan(event_times)): @@ -206,17 +187,15 @@ def add_to_nwbfile( ) continue # Skip if all times are NaNs event_values = name_to_values[event_dict["name"]] - event_type = event_type_name_to_row[event_dict["name"]] - for event_time, event_value in zip(event_times, event_values): - valued_events_table.add_row(timestamp=event_time, event_type=event_type, value=event_value) - if len(events_table) > 0: - behavior_module.add(events_table) + valued_events_table.add_event_type( + label=event_dict["name"], + event_description=event_dict["description"], + event_times=event_times, + value=event_values, + ) if len(valued_events_table) > 0: behavior_module.add(valued_events_table) - task = Task(event_types=event_types_table) - nwbfile.add_lab_meta_data(task) - # Add Trials Table for start_time, stop_time in zip(trial_start_times, trial_stop_times): nwbfile.add_trial(start_time=start_time, stop_time=stop_time) @@ -228,9 +207,10 @@ def add_to_nwbfile( # Add Epochs Table nwbfile.add_epoch(start_time=trial_start_times[0], stop_time=trial_stop_times[-1], tags=["Active Behavior"]) if len(valued_events_table) > 0: + tuning_tone_times = valued_events_table[0].event_times[0] nwbfile.add_epoch( - start_time=valued_events_table["timestamp"][0], - stop_time=valued_events_table["timestamp"][-1], + start_time=tuning_tone_times[0], + stop_time=tuning_tone_times[-1], tags=["Passive Listening"], ) diff --git a/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_convert_session.py b/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_convert_session.py index 702e4fd..32df239 100644 --- a/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_convert_session.py +++ b/src/schneider_lab_to_nwb/zempolich_2024/zempolich_2024_convert_session.py @@ -125,7 +125,7 @@ def main(): data_dir_path = Path("/Volumes/T7/CatalystNeuro/Schneider/Grant Zempolich Project Data") output_dir_path = Path("/Volumes/T7/CatalystNeuro/Schneider/conversion_nwb") stub_test = False - verbose = False + verbose = True if output_dir_path.exists(): shutil.rmtree(output_dir_path, ignore_errors=True)