-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from catalystneuro/epoch
Epoch
- Loading branch information
Showing
12 changed files
with
434 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
from .olson_2024_behavior_interface import Olson2024BehaviorInterface | ||
from .olson_2024_video_interface import Olson2024VideoInterface | ||
from .olson_2024_dlc_interface import Olson2024DeepLabCutInterface | ||
from .olson_2024_spike_gadgets_recording_interface import Olson2024SpikeGadgetsRecordingInterface | ||
from .olson_2024_sorting_interface import Olson2024SortingInterface | ||
from .olson_2024_spike_gadgets_lfp_interface import Olson2024SpikeGadgetsLFPInterface | ||
from .olson_2024_nwbconverter import Olson2024NWBConverter | ||
from .olson_2024_epoch_interface import Olson2024EpochInterface | ||
from .olson_2024_nwbconverter import Olson2024NWBConverter, get_start_datetime |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/jadhav_lab_to_nwb/olson_2024/olson_2024_dlc_interface.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
"""Primary class for converting experiment-specific behavioral video.""" | ||
from pynwb.file import NWBFile | ||
from pydantic import FilePath | ||
from typing import Optional | ||
|
||
from neuroconv.utils import DeepDict, dict_deep_update | ||
from neuroconv.basedatainterface import BaseDataInterface | ||
from neuroconv.datainterfaces import DeepLabCutInterface | ||
|
||
from .utils.utils import get_epoch_name | ||
|
||
|
||
class Olson2024DeepLabCutInterface(BaseDataInterface): | ||
"""DeepLabCut interface for olson_2024 conversion""" | ||
|
||
keywords = ("DLC",) | ||
|
||
def __init__( | ||
self, | ||
file_paths: list[FilePath], | ||
config_file_paths: Optional[list[FilePath]] = None, | ||
subject_name: str = "ind1", | ||
verbose: bool = True, | ||
): | ||
# file_paths must be sorted in the order that the videos were recorded | ||
assert len(file_paths) > 0, "At least one file path must be provided." | ||
if config_file_paths is None: | ||
config_file_paths = [None] * len(file_paths) | ||
assert len(file_paths) == len( | ||
config_file_paths | ||
), "The number of file paths must match the number of config file paths." | ||
dlc_interfaces = [] | ||
for file_path, config_file_path in zip(file_paths, config_file_paths): | ||
dlc_interface = DeepLabCutInterface( | ||
file_path=file_path, | ||
config_file_path=config_file_path, | ||
subject_name=subject_name, | ||
verbose=verbose, | ||
) | ||
dlc_interfaces.append(dlc_interface) | ||
self.dlc_interfaces = dlc_interfaces | ||
|
||
def get_metadata(self) -> DeepDict: | ||
metadata = super().get_metadata() | ||
for dlc_interface in self.dlc_interfaces: | ||
metadata = dict_deep_update(metadata, dlc_interface.get_metadata()) | ||
return metadata | ||
|
||
def get_metadata_schema(self) -> DeepDict: | ||
metadata_schema = super().get_metadata_schema() | ||
for dlc_interface in self.dlc_interfaces: | ||
metadata_schema = dict_deep_update(metadata_schema, dlc_interface.get_metadata_schema()) | ||
return metadata_schema | ||
|
||
def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): | ||
for dlc_interface in self.dlc_interfaces: | ||
file_path = dlc_interface.source_data["file_path"] | ||
epoch_name = get_epoch_name(name=file_path.name) | ||
dlc_interface.add_to_nwbfile( | ||
nwbfile=nwbfile, metadata=metadata, container_name=f"PoseEstimation_{epoch_name}" | ||
) |
93 changes: 93 additions & 0 deletions
93
src/jadhav_lab_to_nwb/olson_2024/olson_2024_epoch_interface.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"""Primary class for converting experiment-specific behavior.""" | ||
from pynwb.file import NWBFile | ||
from pydantic import DirectoryPath | ||
import numpy as np | ||
|
||
from neuroconv.basedatainterface import BaseDataInterface | ||
from .tools.spikegadgets import readCameraModuleTimeStamps | ||
from .utils.utils import get_epoch_name | ||
|
||
|
||
class Olson2024EpochInterface(BaseDataInterface): | ||
"""Epoch interface for olson_2024 conversion""" | ||
|
||
keywords = ("behavior",) | ||
|
||
def __init__(self, epoch_folder_paths: list[DirectoryPath]): | ||
super().__init__(epoch_folder_paths=epoch_folder_paths) | ||
|
||
def get_metadata_schema(self): | ||
metadata_schema = super().get_metadata_schema() | ||
metadata_schema["properties"]["Epochs"] = { | ||
"description": "Metadata for each epoch", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"name": {"type": "string"}, | ||
"task_name": {"type": "string"}, | ||
"led_configuration": {"type": "string"}, | ||
"led_list": {"type": "array", "items": {"type": "string"}}, | ||
"led_positions": {"type": "array", "items": {"type": "string"}}, | ||
}, | ||
"required": ["name", "task_name", "led_configuration", "led_list", "led_positions"], | ||
}, | ||
} | ||
metadata_schema["properties"]["Tasks"] = { | ||
"description": "Metadata for each task", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"name": {"type": "string"}, | ||
"description": {"type": "string"}, | ||
"camera_id": {"type": "string"}, | ||
}, | ||
"required": ["name", "description", "camera_id"], | ||
}, | ||
} | ||
return metadata_schema | ||
|
||
def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): | ||
epoch_folder_paths = self.source_data["epoch_folder_paths"] | ||
nwbfile.add_epoch_column(name="epoch_name", description="Full name of the epoch") | ||
nwbfile.add_epoch_column(name="epoch_id", description="Epoch ID") | ||
nwbfile.add_epoch_column(name="frag_id", description="Frag ID") # TODO: What is a frag ID? | ||
nwbfile.add_epoch_column(name="env_id", description="Environment ID") | ||
nwbfile.add_epoch_column(name="task_id", description="Task ID") | ||
nwbfile.add_epoch_column(name="task_name", description="Full name of the task") | ||
nwbfile.add_epoch_column(name="task_description", description="Description of the task") | ||
nwbfile.add_epoch_column(name="camera_id", description="Camera ID") | ||
nwbfile.add_epoch_column(name="led_configuration", description="LED configuration") | ||
nwbfile.add_epoch_column(name="led_list", description="Comma-separated list of LEDs") | ||
nwbfile.add_epoch_column(name="led_positions", description="Comma-separated list of LED positions") | ||
for epoch_folder_path in epoch_folder_paths: | ||
epoch_name = get_epoch_name(epoch_folder_path.name) | ||
epoch_id, frag_id, env_id, task_id = epoch_name.split("_") | ||
epoch_metadata = next(meta for meta in metadata["Epochs"] if meta["name"] == epoch_id) | ||
task_name = epoch_metadata["task_name"] | ||
task_metadata = next(meta for meta in metadata["Tasks"] if meta["name"] == task_name) | ||
task_description = task_metadata["description"] | ||
camera_id = task_metadata["camera_id"] | ||
led_configuration = epoch_metadata["led_configuration"] | ||
led_list = ",".join(epoch_metadata["led_list"]) | ||
led_positions = ",".join(epoch_metadata["led_positions"]) | ||
video_timestamps_file_path = epoch_folder_path / f"{epoch_folder_path.name}.1.videoTimeStamps" | ||
timestamps, _ = readCameraModuleTimeStamps(video_timestamps_file_path) | ||
start_time = timestamps[0] | ||
stop_time = timestamps[-1] | ||
nwbfile.add_epoch( | ||
start_time=start_time, | ||
stop_time=stop_time, | ||
epoch_name=epoch_name, | ||
epoch_id=epoch_id, | ||
frag_id=frag_id, | ||
env_id=env_id, | ||
task_id=task_id, | ||
task_name=task_name, | ||
task_description=task_description, | ||
camera_id=camera_id, | ||
led_configuration=led_configuration, | ||
led_list=led_list, | ||
led_positions=led_positions, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.