diff --git a/src/jdb_to_nwb/convert.py b/src/jdb_to_nwb/convert.py index b16d4e2..ca43974 100644 --- a/src/jdb_to_nwb/convert.py +++ b/src/jdb_to_nwb/convert.py @@ -3,9 +3,11 @@ import yaml from pynwb import NWBFile, NWBHDF5IO +from pynwb.file import Subject from datetime import datetime from dateutil import tz +from . import __version__ from .convert_raw_ephys import add_raw_ephys from .convert_spikes import add_spikes from .convert_behavior import add_behavior @@ -19,17 +21,42 @@ def create_nwbs( with open(metadata_file_path, "r") as f: metadata = yaml.safe_load(f) + # parse subject metadata + subject = Subject(**metadata["subject"]) + + # parse surgery metadata + surgery = "..." # TODO parse from structured metadata + # TODO: read these from metadata nwbfile = NWBFile( - session_description="Mock session", - session_start_time=datetime.now(tz.tzlocal()), - identifier="mock_session", + session_description="Mock session", # TODO: generate this from metadata + session_start_time=datetime.now(tz.tzlocal()), # TODO: update this + identifier="mock_session", # TODO: update this + session_id=metadata.get("session_id"), + surgery=surgery, + notes=metadata.get("notes"), + experimenter=metadata.get("experimenter"), + institution=metadata.get("institution"), + lab=metadata.get("lab"), + keywords=metadata.get("keywords"), + experiment_description=metadata.get("experiment_description"), + related_publications=metadata.get("related_publications"), + subject=subject, + source_script="jdb_to_nwb " + __version__, + source_script_file_name="convert.py", ) + # if photometry is present, timestamps should be aligned to the photometry + add_photometry(nwbfile=nwbfile, metadata=metadata) + photometry_start_in_arduino_time = add_behavior(nwbfile=nwbfile, metadata=metadata) + add_raw_ephys(nwbfile=nwbfile, metadata=metadata) add_spikes(nwbfile=nwbfile, metadata=metadata) - photometry_start_in_arduino_time = add_behavior(nwbfile=nwbfile, metadata=metadata) - add_photometry(nwbfile=nwbfile, metadata=metadata) + + # TODO: time alignment + + # reset the session start time to the earliest of the data streams + nwbfile.fields["session_start_time"] = datetime.now(tz.tzlocal()) print(f"Writing file, including iterative read from raw ephys data...") @@ -45,4 +72,4 @@ def cli(): parser.add_argument("output_nwb_file_path", type=Path, help="Path to the output NWB file.") args = parser.parse_args() - create_nwbs(args.metadata_file_path, args.output_nwb_file_path) \ No newline at end of file + create_nwbs(args.metadata_file_path, args.output_nwb_file_path) diff --git a/src/plotting/plot_ephys.py b/src/plotting/plot_ephys.py new file mode 100644 index 0000000..c1fe1c7 --- /dev/null +++ b/src/plotting/plot_ephys.py @@ -0,0 +1,2 @@ +def plot_channel_map(): + pass diff --git a/src/plotting/plot_photometry.py b/src/plotting/plot_photometry.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/metadata_full.yaml b/tests/metadata_full.yaml index b3f9f34..8cc46f6 100644 --- a/tests/metadata_full.yaml +++ b/tests/metadata_full.yaml @@ -10,9 +10,10 @@ ephys: plug_order: "chip_first" # must be either "chip_first" or "cable_first", "chip_first" is the default if none specified # For now, there is just one device, which is the probe device: - name: "Probe" - description: "Berke Lab Probe" - manufacturer: "My Manufacturer" + name: "256-ch Silicon Probe, 3mm length, 66um pitch" + # 3mm will be always 66, and 6mm will be always 80 + description: "32 shanks, 8 electrodes per shank. Each shank is 66um apart. The length of each shank is 3mm." + manufacturer: "Daniel Egert, Berke Lab" # Specify both "phot_file_path" and "box_file_path" for raw LabVIEW data, # OR "signals_mat_file_path" for preprocessed LabVIEW data, @@ -23,11 +24,71 @@ photometry: box_file_path: "tests/test_data/downloaded/IM-1478/07252022/IM-1478_2022-07-25_15-24-22____Tim_Conditioning.box" # ppd_file_path: "" + # TODO + # virus_injection_metadata: + # - + # fiber_metadata: + # - + + behavior: arduino_text_file_path: "tests/test_data/behavior/arduinoraw0.txt" arduino_timestamps_file_path: "tests/test_data/behavior/ArduinoStamps0.csv" maze_configuration_file_path: "tests/test_data/behavior/barriers.txt" + behavioral_info: + reward_type: sucrose solution (10% sucrose, 0.1% NaCl) + reward_amount_in_uL: 15 + deprivation_type: water # water (default) or food video: file_path: "../data/video/video.mp4" - timestamps_file_path: "../data/photometry/07252022/timestamps.csv" \ No newline at end of file + timestamps_file_path: "../data/photometry/07252022/timestamps.csv" + +animal_name: "IM-1478" +date: "07252022" # MMDDYYYY or YYYYMMDD + +subject: + subject_id: "IM-1478" + species: Rattus norvegicus + strain: Long Evans + sex: M + date_of_birth: "2022-07-25" + description: A male, Long Evans, wild-type rat. + +session_id: "IM-1478_07252022" + +# surgical notes, one dictionary per surgery +surgeries: + - description: The virus was injected in the left nucleus accumbens core on 2022-01-01. + date: 2022-01-01 + type: virus_injection # virus_injection OR probe_implantation + - description: The probe was implanted in the left nucleus accumbens core on 2022-02-01. + date: 2022-02-01 + type: probe_implantation # virus_injection OR probe_implantation + +notes: + This was a barrier shift task. + +experimenter: + - Crater, Stephanie + - Figueroa, Jose + - Hwang, Yang-Sun + - Krausz, Tim + +institution: University of California, San Francisco + +lab: Berke Lab + +keywords: + - photometry + - ephys + - behavior + - video + - hex maze + - dopamine + - reward + +experiment_description: | + This experiment was performed to test the effects of dopamine on behavior. + +# related_publications: "doi: 10.1016/j.neuron.2023.07.017"