From de1f15a93cc75a14ea05476ee8fe49f7b4f004a6 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Thu, 3 Oct 2024 14:06:38 -0700 Subject: [PATCH 01/13] added opto --- .../schneider_2024/__init__.py | 1 + .../schneider_2024_convert_session.py | 6 +++++- .../schneider_2024/schneider_2024_metadata.yaml | 15 +++++++++++++++ .../schneider_2024/schneider_2024_notes.md | 7 +++++++ .../schneider_2024/schneider_2024_nwbconverter.py | 3 ++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/__init__.py b/src/schneider_lab_to_nwb/schneider_2024/__init__.py index eafd574..e80ad1a 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/__init__.py +++ b/src/schneider_lab_to_nwb/schneider_2024/__init__.py @@ -1,2 +1,3 @@ from .schneider_2024_behaviorinterface import Schneider2024BehaviorInterface +from .schneider_2024_optogeneticinterface import Schneider2024OptogeneticInterface from .schneider_2024_nwbconverter import Schneider2024NWBConverter diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py index a9aa167..ea33e9c 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py @@ -59,6 +59,10 @@ def session_to_nwb( source_data.update({metadata_key_name: dict(file_paths=[video_file_path], metadata_key_name=metadata_key_name)}) conversion_options.update({metadata_key_name: dict()}) + # Add Optogenetic + source_data.update(dict(Optogenetic=dict(file_path=behavior_file_path))) + conversion_options.update(dict(Optogenetic=dict())) + converter = Schneider2024NWBConverter(source_data=source_data) # Add datetime to conversion @@ -113,7 +117,7 @@ def main(): sorting_folder_path = ( data_dir_path / "Schneider sample Data" / "Processed Ephys" / "m69_2023-10-31_17-24-15_Day1_A1" ) - behavior_file_path = data_dir_path / "NWB_Share" / "Sample behavior data" / "m74_ephysSample.mat" + behavior_file_path = data_dir_path / "NWB_Share" / "Sample behavior data" / "m74_optoSample.mat" video_folder_path = data_dir_path / "Schneider sample Data" / "Video" / "m69_231031" session_to_nwb( recording_folder_path=recording_folder_path, diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 24d1541..eac7d07 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -87,3 +87,18 @@ Behavior: Sorting: units_description: Neural spikes will be sorted offline using Kilosort 2.5 and Phy2 software and manually curated to ensure precise spike time acquisition. + +Optogenetics: + Device: + name: optogenetic_stimulation_laser + description: Real time optogenetic stimulation of brain regions of interest will be accomplished via TTL control of an all solidstate 473nm blue laser (MBL-III-473/1~100mW, Opto Engine LLC). Bifurcated fiber cables (ThorLabs, Ø200 µm Core Multimode Fiber) will be used for light delivery. + manufacturer: Opto Engine LLC + OptogeneticStimulusSite: + name: optogenetic_stimulus_site + description: To identify cortical neurons that project from AC to motor regions (Aim 2), stereotaxic injections of AAV-ChR2 will be made into AC (-2.8 AP, 4.2 ML relative to bregma; guided by intrinsic optical imaging) during head-fixation and animals will be trained while expression occurs (~2 weeks). In addition, fiber optics will be implanted to target cell bodies in the striatum (+ 0.9 AP, 1.8 ML, -2.3 DV). + excitation_lambda: 473.0 # nm + injection_location: Primary Auditory Cortex (-2.8 AP, 4.2 ML relative to bregma; guided by intrinsic optical imaging) + stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) + OptogeneticSeries: + name: optogenetic_series + description: On experiment day before recording, 100ms pulses of 473nm light will be delivered over striatum (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons (Figure 4A), generating antidromic spikes in the direction towards AC whereby we can then identify motor-regionprojecting AC cells via offline analysis of action potential latency to the light stimulus (see preliminary data Aim 2). diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md index 54ac346..b02abbb 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md @@ -4,6 +4,13 @@ ## Video +## Optogenetics +- How to distinguish between 473nm stim in striatum w/ AAV-ChR2 and 532nm stim in A1 w/ AAV-FLEx-Arch+AAV-Retro-Cre? +- Opto stim frequency? +- Per trial power? 100mW? 300mW? +- Pulse width for 532nm stim (also 100ms)? +- There is one trial at the end of the behavioral session that is 1 for opto_trial but nan for stim onset and offset times. What to do? + ## Data Requests - Mice sexes - Remaining data for Grant's project diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_nwbconverter.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_nwbconverter.py index 5b1d40e..eccd407 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_nwbconverter.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_nwbconverter.py @@ -7,7 +7,7 @@ ) from neuroconv.basedatainterface import BaseDataInterface -from schneider_lab_to_nwb.schneider_2024 import Schneider2024BehaviorInterface +from schneider_lab_to_nwb.schneider_2024 import Schneider2024BehaviorInterface, Schneider2024OptogeneticInterface class Schneider2024NWBConverter(NWBConverter): @@ -19,4 +19,5 @@ class Schneider2024NWBConverter(NWBConverter): Behavior=Schneider2024BehaviorInterface, VideoCamera1=VideoInterface, VideoCamera2=VideoInterface, + Optogenetic=Schneider2024OptogeneticInterface, ) From d4f3a576d20e278ea0aea63e5f80a7620ede13d1 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Thu, 3 Oct 2024 14:06:55 -0700 Subject: [PATCH 02/13] added opto --- .../schneider_2024_optogeneticinterface.py | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py new file mode 100644 index 0000000..c698a0c --- /dev/null +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py @@ -0,0 +1,88 @@ +"""Primary class for converting optogenetic stimulation.""" +from pynwb.file import NWBFile +from pydantic import FilePath +import numpy as np +from pymatreader import read_mat +from pynwb.device import Device +from pynwb.ogen import OptogeneticSeries, OptogeneticStimulusSite + +from neuroconv.basedatainterface import BaseDataInterface +from neuroconv.tools.optogenetics import create_optogenetic_stimulation_timeseries +from neuroconv.utils import DeepDict, get_base_schema +from neuroconv.tools import nwb_helpers + + +class Schneider2024OptogeneticInterface(BaseDataInterface): + """Optogenetic interface for schneider_2024 conversion""" + + keywords = ["optogenetics"] + + def __init__(self, file_path: FilePath): + super().__init__(file_path=file_path) + + def get_metadata(self) -> DeepDict: + metadata = super().get_metadata() + + return metadata + + def get_metadata_schema(self) -> dict: + metadata_schema = super().get_metadata_schema() + return metadata_schema + + def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): + # Read Data + file_path = self.source_data["file_path"] + file = read_mat(file_path) + onset_times = file["events"]["push"]["opto_time"] + is_opto_trial = np.logical_not(np.isnan(onset_times)) + onset_times = onset_times[is_opto_trial] + offset_times = file["events"]["push"]["opto_time_end"] + offset_times = offset_times[is_opto_trial] + assert np.all( + np.logical_not(np.isnan(offset_times)) + ), "Some of the offset times are nan when onset times are not nan." + frequency = 1 # TODO: Get opto stim frequency from schneider lab + power = 0.1 # TODO: confirm power with schneider lab + pulse_width = 0.1 # TODO: confirm pulse width with schneider lab + + timestamps, data = [0], [0] + for onset_time, offset_time in zip(onset_times, offset_times): + duration = offset_time - onset_time + num_pulses = int(duration * frequency) + inter_pulse_interval = 1 / frequency + for i in range(num_pulses): + pulse_onset_time = onset_time + i * inter_pulse_interval + timestamps.append(pulse_onset_time) + data.append(power) + pulse_offset_time = pulse_onset_time + pulse_width + timestamps.append(pulse_offset_time) + data.append(0) + timestamps, data = np.array(timestamps, dtype=np.float64), np.array(data, dtype=np.float64) + + # Add Data to NWBFile + # Add Device + device = Device(**metadata["Optogenetics"]["Device"]) + nwbfile.add_device(device) + + # Add OptogeneticStimulusSite + site_metadata = metadata["Optogenetics"]["OptogeneticStimulusSite"] + location = f"Injection location: {site_metadata['injection_location']} \n Stimulation location: {site_metadata['stimulation_location']}" + ogen_site = OptogeneticStimulusSite( + name=site_metadata["name"], + device=device, + description=site_metadata["description"], + excitation_lambda=site_metadata["excitation_lambda"], + location=location, + ) + nwbfile.add_ogen_site(ogen_site) + + # Add OptogeneticSeries + series_metadata = metadata["Optogenetics"]["OptogeneticSeries"] + optogenetic_series = OptogeneticSeries( + name=series_metadata["name"], + site=ogen_site, + description=series_metadata["description"], + data=data, + timestamps=timestamps, + ) + nwbfile.add_stimulus(optogenetic_series) From e57d065bb88336feee6a22abf58f80a632e5ae55 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 10:46:39 -0700 Subject: [PATCH 03/13] updated opto params --- .../schneider_2024_optogeneticinterface.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py index c698a0c..a380726 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py @@ -41,22 +41,14 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): assert np.all( np.logical_not(np.isnan(offset_times)) ), "Some of the offset times are nan when onset times are not nan." - frequency = 1 # TODO: Get opto stim frequency from schneider lab - power = 0.1 # TODO: confirm power with schneider lab - pulse_width = 0.1 # TODO: confirm pulse width with schneider lab + power = 0.02 # 15-20mW timestamps, data = [0], [0] for onset_time, offset_time in zip(onset_times, offset_times): - duration = offset_time - onset_time - num_pulses = int(duration * frequency) - inter_pulse_interval = 1 / frequency - for i in range(num_pulses): - pulse_onset_time = onset_time + i * inter_pulse_interval - timestamps.append(pulse_onset_time) - data.append(power) - pulse_offset_time = pulse_onset_time + pulse_width - timestamps.append(pulse_offset_time) - data.append(0) + timestamps.append(onset_time) + data.append(power) + timestamps.append(offset_time) + data.append(0) timestamps, data = np.array(timestamps, dtype=np.float64), np.array(data, dtype=np.float64) # Add Data to NWBFile From 523560e0f9ab7084025d94a8178253ff0afa489a Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 10:50:13 -0700 Subject: [PATCH 04/13] moved power to the metadata --- .../schneider_2024/schneider_2024_metadata.yaml | 1 + .../schneider_2024/schneider_2024_optogeneticinterface.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index eac7d07..443e0bc 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -102,3 +102,4 @@ Optogenetics: OptogeneticSeries: name: optogenetic_series description: On experiment day before recording, 100ms pulses of 473nm light will be delivered over striatum (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons (Figure 4A), generating antidromic spikes in the direction towards AC whereby we can then identify motor-regionprojecting AC cells via offline analysis of action potential latency to the light stimulus (see preliminary data Aim 2). + power: 0.020 # 15-20 mW diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py index a380726..12e0e0a 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py @@ -41,7 +41,7 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): assert np.all( np.logical_not(np.isnan(offset_times)) ), "Some of the offset times are nan when onset times are not nan." - power = 0.02 # 15-20mW + power = metadata["Optogenetics"]["OptogeneticSeries"]["power"] timestamps, data = [0], [0] for onset_time, offset_time in zip(onset_times, offset_times): From 612218845af84e0756156d5255c7ffff0049b330 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 10:57:36 -0700 Subject: [PATCH 05/13] updated optogenetic series description --- .../schneider_2024/schneider_2024_metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 443e0bc..8fc98f7 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -101,5 +101,5 @@ Optogenetics: stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) OptogeneticSeries: name: optogenetic_series - description: On experiment day before recording, 100ms pulses of 473nm light will be delivered over striatum (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons (Figure 4A), generating antidromic spikes in the direction towards AC whereby we can then identify motor-regionprojecting AC cells via offline analysis of action potential latency to the light stimulus (see preliminary data Aim 2). + description: On experiment day before recording, continuous wave stimulation of 473nm light will be delivered over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. power: 0.020 # 15-20 mW From c9e5ae1dbc95ebfdda3986cc8420174949388102 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 10:58:13 -0700 Subject: [PATCH 06/13] updated optogenetic series description --- .../schneider_2024/schneider_2024_metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 8fc98f7..88d036a 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -101,5 +101,5 @@ Optogenetics: stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) OptogeneticSeries: name: optogenetic_series - description: On experiment day before recording, continuous wave stimulation of 473nm light will be delivered over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. + description: On experiment day before recording, continuous wave stimulation of 473nm light (15-20mW) will be delivered over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. power: 0.020 # 15-20 mW From b69fd17637ab52907bc7e377c0306e192763f6ab Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 11:02:43 -0700 Subject: [PATCH 07/13] updated optogenetic series description --- .../schneider_2024/schneider_2024_metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 88d036a..8504642 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -101,5 +101,5 @@ Optogenetics: stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) OptogeneticSeries: name: optogenetic_series - description: On experiment day before recording, continuous wave stimulation of 473nm light (15-20mW) will be delivered over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. + description: On experiment day before recording, continuous wave stimulation of 473nm light (15-20mW) will be delivered bilaterally over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. power: 0.020 # 15-20 mW From 5d03382fd882dd1ea0b2bebb5998049e01234688 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 7 Oct 2024 11:04:57 -0700 Subject: [PATCH 08/13] updated optogenetic series description --- .../schneider_2024/schneider_2024_metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 8504642..203b0ac 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -101,5 +101,5 @@ Optogenetics: stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) OptogeneticSeries: name: optogenetic_series - description: On experiment day before recording, continuous wave stimulation of 473nm light (15-20mW) will be delivered bilaterally over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. + description: In optogenetic perturbation trials (~33% of trials), during each lever press, continuous wave stimulation of 473nm light (15-20mW) will be delivered bilaterally over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. power: 0.020 # 15-20 mW From 2a570e9dd19487c8af6a752779434179d8a391ab Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 9 Oct 2024 09:04:01 -0700 Subject: [PATCH 09/13] Union[str, Path] --> str | Path --- .../schneider_2024_convert_all_sessions.py | 27 +++++++++---------- .../schneider_2024_convert_session.py | 11 ++++---- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_all_sessions.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_all_sessions.py index 0d59044..8cb5833 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_all_sessions.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_all_sessions.py @@ -1,6 +1,5 @@ """Primary script to run to convert all sessions in a dataset using session_to_nwb.""" from pathlib import Path -from typing import Union from concurrent.futures import ProcessPoolExecutor, as_completed from pprint import pformat import traceback @@ -11,8 +10,8 @@ def dataset_to_nwb( *, - data_dir_path: Union[str, Path], - output_dir_path: Union[str, Path], + data_dir_path: str | Path, + output_dir_path: str | Path, max_workers: int = 1, verbose: bool = True, ): @@ -20,9 +19,9 @@ def dataset_to_nwb( Parameters ---------- - data_dir_path : Union[str, Path] + data_dir_path : str | Path The path to the directory containing the raw data. - output_dir_path : Union[str, Path] + output_dir_path : str | Path The path to the directory where the NWB files will be saved. max_workers : int, optional The number of workers to use for parallel processing, by default 1 @@ -39,7 +38,7 @@ def dataset_to_nwb( for session_to_nwb_kwargs in session_to_nwb_kwargs_per_session: session_to_nwb_kwargs["output_dir_path"] = output_dir_path session_to_nwb_kwargs["verbose"] = verbose - exception_file_path = data_dir_path / f"ERROR_.txt" # Add error file path here + exception_file_path = data_dir_path / f"ERROR_.txt" # Add error file path here futures.append( executor.submit( safe_session_to_nwb, @@ -51,7 +50,7 @@ def dataset_to_nwb( pass -def safe_session_to_nwb(*, session_to_nwb_kwargs: dict, exception_file_path: Union[Path, str]): +def safe_session_to_nwb(*, session_to_nwb_kwargs: dict, exception_file_path: str | Path): """Convert a session to NWB while handling any errors by recording error messages to the exception_file_path. Parameters @@ -72,13 +71,13 @@ def safe_session_to_nwb(*, session_to_nwb_kwargs: dict, exception_file_path: Uni def get_session_to_nwb_kwargs_per_session( *, - data_dir_path: Union[str, Path], + data_dir_path: str | Path, ): """Get the kwargs for session_to_nwb for each session in the dataset. Parameters ---------- - data_dir_path : Union[str, Path] + data_dir_path : str | Path The path to the directory containing the raw data. Returns @@ -86,11 +85,11 @@ def get_session_to_nwb_kwargs_per_session( list[dict[str, Any]] A list of dictionaries containing the kwargs for session_to_nwb for each session. """ - ##### - # # Implement this function to return the kwargs for session_to_nwb for each session - # This can be a specific list with hard-coded sessions, a path expansion or any conversion specific logic that you might need - ##### - raise NotImplementedError + ##### + # # Implement this function to return the kwargs for session_to_nwb for each session + # This can be a specific list with hard-coded sessions, a path expansion or any conversion specific logic that you might need + ##### + raise NotImplementedError if __name__ == "__main__": diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py index ea33e9c..515106b 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_convert_session.py @@ -1,6 +1,5 @@ """Primary script to run to convert an entire session for of data using the NWBConverter.""" from pathlib import Path -from typing import Union import datetime import pytz from zoneinfo import ZoneInfo @@ -13,11 +12,11 @@ def session_to_nwb( - recording_folder_path: Union[str, Path], - sorting_folder_path: Union[str, Path], - behavior_file_path: Union[str, Path], - video_folder_path: Union[str, Path], - output_dir_path: Union[str, Path], + recording_folder_path: str | Path, + sorting_folder_path: str | Path, + behavior_file_path: str | Path, + video_folder_path: str | Path, + output_dir_path: str | Path, stub_test: bool = False, ): recording_folder_path = Path(recording_folder_path) From 83c05ccc95c49f7f1e6ac1e3aecb9412a1c346a0 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 21 Oct 2024 09:31:45 -0700 Subject: [PATCH 10/13] updated opto stim site description --- .../schneider_2024/schneider_2024_metadata.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml index 203b0ac..124fd24 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_metadata.yaml @@ -95,10 +95,10 @@ Optogenetics: manufacturer: Opto Engine LLC OptogeneticStimulusSite: name: optogenetic_stimulus_site - description: To identify cortical neurons that project from AC to motor regions (Aim 2), stereotaxic injections of AAV-ChR2 will be made into AC (-2.8 AP, 4.2 ML relative to bregma; guided by intrinsic optical imaging) during head-fixation and animals will be trained while expression occurs (~2 weeks). In addition, fiber optics will be implanted to target cell bodies in the striatum (+ 0.9 AP, 1.8 ML, -2.3 DV). + description: To identify cortical neurons that project from the auditory cortex to motor regions (Aim 2), stereotaxic injections of AAV-ChR2 will be made into the primary auditory cortex (-2.8 AP, 4.2 ML relative to bregma; guided by intrinsic optical imaging) during head-fixation and animals will be trained while expression occurs (~2 weeks). In addition, fiber optics will be implanted to target cell bodies in the secondary motor cortex (1.0-1.5 AP, 0.5-0.7 ML). excitation_lambda: 473.0 # nm injection_location: Primary Auditory Cortex (-2.8 AP, 4.2 ML relative to bregma; guided by intrinsic optical imaging) - stimulation_location: Striatum (+ 0.9 AP, 1.8 ML, -2.3 DV) + stimulation_location: Secondary Motor Cortex (1.0-1.5 AP, 0.5-0.7 ML) OptogeneticSeries: name: optogenetic_series description: In optogenetic perturbation trials (~33% of trials), during each lever press, continuous wave stimulation of 473nm light (15-20mW) will be delivered bilaterally over primary auditory cortex A1 (or secondary motor cortex, M2, as necessary using similar protocol - see Aim 2) to activate the terminals of ChR2 expressing neurons. From 341171b114dd8042ea61d8a881f3417b19650ee9 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 21 Oct 2024 09:36:54 -0700 Subject: [PATCH 11/13] updated notes --- .../schneider_2024/schneider_2024_notes.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md index b02abbb..4d75a52 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_notes.md @@ -5,11 +5,8 @@ ## Video ## Optogenetics -- How to distinguish between 473nm stim in striatum w/ AAV-ChR2 and 532nm stim in A1 w/ AAV-FLEx-Arch+AAV-Retro-Cre? -- Opto stim frequency? -- Per trial power? 100mW? 300mW? -- Pulse width for 532nm stim (also 100ms)? -- There is one trial at the end of the behavioral session that is 1 for opto_trial but nan for stim onset and offset times. What to do? +- is_opto_trial in the trials table is `np.logical_not(np.isnan(onset_times))` rather than reading from the .mat file + to ensure consistency with the onset/offset times. ## Data Requests - Mice sexes From 4c85abf73ae122e2182822f873aa0b2d5d059789 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 21 Oct 2024 09:45:40 -0700 Subject: [PATCH 12/13] removed unused imports --- .../schneider_2024/schneider_2024_optogeneticinterface.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py index 12e0e0a..68965b9 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py @@ -7,9 +7,7 @@ from pynwb.ogen import OptogeneticSeries, OptogeneticStimulusSite from neuroconv.basedatainterface import BaseDataInterface -from neuroconv.tools.optogenetics import create_optogenetic_stimulation_timeseries -from neuroconv.utils import DeepDict, get_base_schema -from neuroconv.tools import nwb_helpers +from neuroconv.utils import DeepDict class Schneider2024OptogeneticInterface(BaseDataInterface): From cb0b044f14ce89542bf35625a8919516790ed1d1 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Tue, 22 Oct 2024 09:44:34 -0700 Subject: [PATCH 13/13] removed 0 at time 0 for ogen series --- .../schneider_2024/schneider_2024_optogeneticinterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py index 68965b9..46b2930 100644 --- a/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py +++ b/src/schneider_lab_to_nwb/schneider_2024/schneider_2024_optogeneticinterface.py @@ -41,7 +41,7 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict): ), "Some of the offset times are nan when onset times are not nan." power = metadata["Optogenetics"]["OptogeneticSeries"]["power"] - timestamps, data = [0], [0] + timestamps, data = [], [] for onset_time, offset_time in zip(onset_times, offset_times): timestamps.append(onset_time) data.append(power)