-
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.
- Loading branch information
1 parent
24f821a
commit d5f2413
Showing
5 changed files
with
202 additions
and
1 deletion.
There are no files selected for viewing
Empty file.
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,107 @@ | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from neuroconv import BaseDataInterface | ||
from pydantic import FilePath | ||
from pynwb import NWBFile | ||
from pynwb import TimeSeries | ||
from pymatreader import read_mat | ||
|
||
|
||
class BehaviorInterface(BaseDataInterface): | ||
def __init__(self, file_path: FilePath): | ||
self.file_path = Path(file_path) | ||
|
||
def add_to_nwbfile( | ||
self, | ||
nwbfile: NWBFile, | ||
metadata: Optional[dict] = None, | ||
) -> None: | ||
|
||
mat = read_mat(self.file_path) | ||
rec_struct = mat["rec"] | ||
daq_struct = rec_struct["daq"] | ||
|
||
timestamps = daq_struct["tstamps"] | ||
|
||
# Extracted from the matlab manually | ||
# neither scipy or pymatreader can read string characters from the .mat file | ||
channel_names = [ | ||
"CamSync", | ||
"CamTrigger", | ||
"OptoTrigger", | ||
"LWingBeatAmp", | ||
"RWingBeatAmp", | ||
"WingBeatFreq", | ||
"LHutchen", | ||
"RHutchen", | ||
"PTrigger", | ||
] | ||
|
||
# TODO: figure how how to store this | ||
# Synchronization signals | ||
cam_sync = daq_struct["data"][:, 0] | ||
cam_trigger = daq_struct["data"][:, 1] | ||
opto_trigger = daq_struct["data"][:, 2] | ||
ptrigger = daq_struct["data"][:, 8] | ||
|
||
# Behavior signals | ||
left_wing_beat_amplitude = daq_struct["data"][:, 3] | ||
right_wing_beat_amplitude = daq_struct["data"][:, 4] | ||
wing_beat_frequency = daq_struct["data"][:, 5] | ||
|
||
unit = "tbd" | ||
description = "tbd" | ||
left_wing_beat_amplitude_time_series = TimeSeries( | ||
name="LeftWingBeatAmplitudeTimeSeries", | ||
data=left_wing_beat_amplitude, | ||
unit=unit, | ||
timestamps=timestamps, | ||
description=description, | ||
) | ||
|
||
description = "tbd" | ||
right_wing_beat_amplitude_time_series = TimeSeries( | ||
name="RightWingBeatAmplitudeTimeSeries", | ||
data=right_wing_beat_amplitude, | ||
unit=unit, | ||
timestamps=timestamps, | ||
description=description, | ||
) | ||
|
||
description = "tbd" | ||
unit = "Hz" # TODO: Figure this out, the values in the plot are around 3 but should be higher for flies | ||
wing_beat_frequency_time_series = TimeSeries( | ||
name="WingBeatFrequencyTimeSeries", | ||
data=wing_beat_frequency, | ||
unit=unit, | ||
timestamps=timestamps, | ||
description=description, | ||
) | ||
|
||
nwbfile.add_acquisition(left_wing_beat_amplitude_time_series) | ||
nwbfile.add_acquisition(right_wing_beat_amplitude_time_series) | ||
nwbfile.add_acquisition(wing_beat_frequency_time_series) | ||
|
||
# TODO: Ask Ben if this nesting makes sense? probably not | ||
# time_series = [left_wing_beat_amplitude_time_series, right_wing_beat_amplitude_time_series, wing_beat_frequency_time_series] | ||
# behavioral_time_series_container = BehavioralTimeSeries(name="BehavioralTimeSeries", time_series=time_series) | ||
# nwbfile.add_acquisition(behavioral_time_series_container) | ||
|
||
# Not clear what are those signals, haltere? | ||
lhutchen = daq_struct["data"][:, 6] | ||
rhutchen = daq_struct["data"][:, 7] | ||
|
||
unit = "tbd" | ||
description = "tbd" | ||
lhutchen_time_series = TimeSeries( | ||
name="LHutchenTimeSeries", data=lhutchen, unit=unit, timestamps=timestamps, description=description | ||
) | ||
|
||
description = "tbd" | ||
rhutchen_time_series = TimeSeries( | ||
name="RHutchenTimeSeries", data=rhutchen, unit=unit, timestamps=timestamps, description=description | ||
) | ||
|
||
nwbfile.add_acquisition(lhutchen_time_series) | ||
nwbfile.add_acquisition(rhutchen_time_series) |
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,73 @@ | ||
from pathlib import Path | ||
import time | ||
from datetime import datetime | ||
from typing import Optional | ||
from zoneinfo import ZoneInfo | ||
from neuroconv.utils import dict_deep_update, load_dict_from_file | ||
|
||
from neuroconv import ConverterPipe | ||
from fox_lab_to_nwb.behavior import BehaviorInterface | ||
|
||
|
||
def run_trial_conversion(trial_data_folder: Path, output_dir_path: Optional[Path] = None, verbose: bool = True): | ||
|
||
if verbose: | ||
start_time = time.time() | ||
|
||
if output_dir_path is None: | ||
output_dir_path = Path.home() / "conversion_nwb" | ||
|
||
# session_id = f"{subject}_{session_date}_{session_time}" | ||
session_id = "session" | ||
nwbfile_path = output_dir_path / f"{session_id}.nwb" | ||
|
||
file_path = trial_data_folder / "Tshx18D07_240124_115923_f3_r1.fly2" | ||
assert file_path.exists(), f"File {file_path} does not exist" | ||
interface = BehaviorInterface(file_path=file_path) | ||
|
||
converter = ConverterPipe(data_interfaces={"behavior": interface}) | ||
|
||
|
||
# Add datetime to conversion | ||
metadata = converter.get_metadata() | ||
session_start_time = datetime.now().astimezone(ZoneInfo("America/New_York")) | ||
metadata["NWBFile"]["session_start_time"] = session_start_time | ||
|
||
# Update default metadata with the editable in the corresponding yaml file | ||
editable_metadata_path = Path(__file__).parent / "metadata.yaml" | ||
editable_metadata = load_dict_from_file(editable_metadata_path) | ||
metadata = dict_deep_update(metadata, editable_metadata) | ||
|
||
subject_metadata = metadata["Subject"] | ||
subject = "subject" | ||
subject_metadata["subject_id"] = f"{subject}" | ||
|
||
# Run conversion, this adds the basic data to the NWBFile | ||
conversion_options = {} | ||
converter.run_conversion( | ||
metadata=metadata, | ||
nwbfile_path=nwbfile_path, | ||
conversion_options=conversion_options, | ||
overwrite=True, | ||
) | ||
|
||
if verbose: | ||
stop_time = time.time() | ||
conversion_time_seconds = stop_time - start_time | ||
if conversion_time_seconds <= 60 * 3: | ||
print(f"Conversion took {conversion_time_seconds:.2f} seconds") | ||
elif conversion_time_seconds <= 60 * 60: | ||
print(f"Conversion took {conversion_time_seconds / 60:.2f} minutes") | ||
else: | ||
print(f"Conversion took {conversion_time_seconds / 60 / 60:.2f} hours") | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
verbose = True | ||
data_path = Path("/home/heberto/cohen_project/Sample data/Fox Lab") | ||
assert data_path.exists(), f"Folder {data_path} does not exist" | ||
trial_data_folder = data_path / "Tshx18D07_240124_115923_f3_r1" | ||
assert trial_data_folder.exists(), f"Folder {trial_data_folder} does not exist" | ||
|
||
run_trial_conversion(trial_data_folder=trial_data_folder, verbose=verbose) |
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
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,20 @@ | ||
NWBFile: | ||
keywords: | ||
- Fly | ||
- Wingbeat | ||
- Behavior | ||
related_publications: | ||
- https://doi.org/great_publication or link to APA or MLA citation of the publication | ||
session_description: | ||
A rich text description of the experiment. Can also just be the abstract of the publication. | ||
experiment_description: 'Task: Rapid serial visual presentation (RSVP).' | ||
institution: Case Western Reserve University | ||
lab: Fox | ||
experimenter: | ||
- Streets, Amy | ||
- Lea, Kriss | ||
surgery: TBD | ||
Subject: | ||
sex: M | ||
species: Drosophila melanogaster # TODO: Figure this one out | ||
description: fly |