From 19a4c4e687d6fa6f94d25596063673f8ff89dfb3 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 12:37:27 -0700 Subject: [PATCH 01/25] resolved problematic photometry sessions --- .../seiler_2024_convert_dataset.py | 4 +-- .../seiler_2024/seiler_2024_notes.md | 31 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 2a7b3af..4c0a063 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -245,11 +245,11 @@ def fp_to_nwb( if ( ( photometry_subject_id == "334.394" and photometry_start_date == "07/21/20" - ) # TODO: Ask Lerner Lab about this session + ) # Skipping this session bc photometry data is corrupted or ( photometry_subject_id == "99.257" and photometry_start_date == "04/16/19" - # TODO: Ask Lerner Lab about this session + # Skipping this session bc missing behavior data ) or ( photometry_subject_id == "64.205" diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 3539698..207c4bd 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -116,10 +116,13 @@ PrtN, RNnR, PrtR, LNPS, RNRW -- why is this mismatched with the expected epocs? for that 1 session split across the two folders? - Answer: Yes, occasionally the computer freezes or something and I need to restart the TDT recording while the MED program is unaffected. For my analysis I basically just stitched them together. - Solution: Added stitching functionality for optional second_folder_path - -### Active Questions - For DPR/334.394/07/21/20, 3 right nosepokes were made BUT photometry object still doesn't have a RNPS object + - Skip this session bc it is corrupted - RR20/99.257 on 04/16/19 has a photometry session but no matching behavior session on that day -- pls provide? + - Skip this session bc Lerner Lab can't find it + +### Active Questions +None ## Optogenetics ### Notes @@ -145,17 +148,6 @@ for that 1 session split across the two folders? - Solution: Metadata excel file has treatment info --> metadata["NWBFile"]["stimulus_notes"] - RI 60 LEFT_STIM, RI 30 LEFT_STIM, and RK_C_FR1_BOTH_1hr msns show up in opto data but don't have associated files -- assumed to be the same as their right counterparts? -## Metadata -### Notes -- Some medpc filenames/sessions have incomplete or missing subject names (ex. 75 instead of 75.214) -- need to do some matching operation -- Punishment Group has a typo for PR ('Punishment Resitant' instead of 'Punishment Resistant') -- I'll fix on my end - -### Questions -- Some of the subject_ids are not present in the metadata excel file -- pls provide -- Some animals are missing the "Hemisphere with DMS" field -- pls provide -======= - - Solution: Added missing MSNs; skipped RK_C_FR1_BOTH_1hr - ### Active Questions - DMS-Excitatory has some csv files w/ only session-aggregated info (total right rewards but not right reward times) ex. ChR2/121_280.CSV -- do you have individual session info for these animals? - Some csv files do not have any subject info (ex. DLS Excitatory/_08-28-20.csv) -- pls provide or we will need to skip these sessions @@ -182,3 +174,16 @@ for that 1 session split across the two folders? start_date ='09/22/20' start_time ='12:43:27' start_date ='09/22/20' start_time ='12:43:27' start_date ='09/22/20' start_time ='12:43:27' + + +## Metadata +### Notes +- Some medpc filenames/sessions have incomplete or missing subject names (ex. 75 instead of 75.214) -- need to do some matching operation +- Punishment Group has a typo for PR ('Punishment Resitant' instead of 'Punishment Resistant') -- I'll fix on my end + +### Resolved Questions +- Some animals are missing the "Hemisphere with DMS" field -- pls provide + - Solution: Added missing MSNs; skipped RK_C_FR1_BOTH_1hr + +### Active Questions +- Some of the subject_ids are not present in the metadata excel file -- pls provide From 0b1ae25969f21a51f47a30c0601cfbe7e1fc763d Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 12:40:57 -0700 Subject: [PATCH 02/25] skip session-aggregated csvs --- .../seiler_2024/seiler_2024_convert_dataset.py | 2 +- src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 4c0a063..5c99c68 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -472,7 +472,7 @@ def opto_to_nwb( if not ( path.name.startswith(".") or path.name.endswith(".csv") - or path.name.endswith(".CSV") # TODO: add support for session-aggregated CSV files + or path.name.endswith(".CSV") # session-aggregated CSV files are skipped ) ] for subject_path in subject_paths: diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 207c4bd..9e2f70a 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -147,9 +147,10 @@ None (ChR2, EYFP, Scrambled). Which treatment did these sessions receive? - Solution: Metadata excel file has treatment info --> metadata["NWBFile"]["stimulus_notes"] - RI 60 LEFT_STIM, RI 30 LEFT_STIM, and RK_C_FR1_BOTH_1hr msns show up in opto data but don't have associated files -- assumed to be the same as their right counterparts? +- DMS-Excitatory has some csv files w/ only session-aggregated info (total right rewards but not right reward times) ex. ChR2/121_280.CSV -- do you have individual session info for these animals? + - Lerner Lab does not have this data --> skip these sessions ### Active Questions -- DMS-Excitatory has some csv files w/ only session-aggregated info (total right rewards but not right reward times) ex. ChR2/121_280.CSV -- do you have individual session info for these animals? - Some csv files do not have any subject info (ex. DLS Excitatory/_08-28-20.csv) -- pls provide or we will need to skip these sessions - Some of the sessions in the DLS Excitatory medpc files organized by date don't have subject info -- pls provide or we will need to skip these sessions Full List: From d42e72aed2b6c41f4dd059eebe0e7b70e0ae6525 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 12:50:16 -0700 Subject: [PATCH 03/25] skip sessions w/o subject info --- .../seiler_2024/seiler_2024_convert_dataset.py | 2 +- src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 5c99c68..782203b 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -526,7 +526,7 @@ def opto_to_nwb( for file in raw_files_by_date_path.iterdir(): if ( file.name.startswith(".") or file.is_dir() or file.suffix == ".csv" - ): # TODO: ask Lerner Lab about orphaned csvs + ): # These .csv files are skipped bc they don't have subject info continue info = get_medpc_variables(file_path=file, variable_names=["Subject", "Start Date", "Start Time", "MSN", "Box"]) for i in range(len(info["Subject"])): diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 9e2f70a..387e533 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -149,9 +149,8 @@ None - RI 60 LEFT_STIM, RI 30 LEFT_STIM, and RK_C_FR1_BOTH_1hr msns show up in opto data but don't have associated files -- assumed to be the same as their right counterparts? - DMS-Excitatory has some csv files w/ only session-aggregated info (total right rewards but not right reward times) ex. ChR2/121_280.CSV -- do you have individual session info for these animals? - Lerner Lab does not have this data --> skip these sessions - -### Active Questions - Some csv files do not have any subject info (ex. DLS Excitatory/_08-28-20.csv) -- pls provide or we will need to skip these sessions + - Lerner Lab does not have this metadata --> skip these sessions - Some of the sessions in the DLS Excitatory medpc files organized by date don't have subject info -- pls provide or we will need to skip these sessions Full List: start_date ='08/28/20' start_time ='14:02:02' @@ -175,7 +174,10 @@ None start_date ='09/22/20' start_time ='12:43:27' start_date ='09/22/20' start_time ='12:43:27' start_date ='09/22/20' start_time ='12:43:27' + - Lerner Lab does not have this metadata --> skip these sessions +### Active Questions +None ## Metadata ### Notes From e70753fc7ae7fb9f11ca1991f84a7fad25c98884 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 12:54:42 -0700 Subject: [PATCH 04/25] added partially corrupted example session --- .../seiler_2024_convert_session.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py index 003bcc7..2e90325 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py @@ -483,6 +483,50 @@ def session_to_nwb( experimental_group=experimental_group, stub_test=stub_test, ) + # Fiber Photometry session with partial corruption AND missing Fi1d AND stitching two sessions together + experiment_type = "FP" + experimental_group = "PS" + subject_id = "139.298" + start_datetime = datetime(2019, 9, 12, 9, 33, 41) + session_conditions = { + "Start Date": start_datetime.strftime("%m/%d/%y"), + "Start Time": start_datetime.strftime("%H:%M:%S"), + } + start_variable = "Start Date" + behavior_file_path = ( + data_dir_path + / f"{experiment_type} Experiments" + / "Behavior" + / f"{experimental_group}" + / f"{subject_id}" + / f"{subject_id}" + ) + fiber_photometry_folder_path = ( + data_dir_path + / f"{experiment_type} Experiments" + / "Photometry" + / f"Punishment Sensitive" + / f"Late RI60" + / f"Photo_{subject_id.split('.')[0]}_{subject_id.split('.')[1]}-190912-095034" + ) + fiber_photometry_t2 = 2267.0 + second_fiber_photometry_folder_path = fiber_photometry_folder_path.parent / "Photo_139_298-190912-103544" + session_to_nwb( + data_dir_path=data_dir_path, + output_dir_path=output_dir_path, + behavior_file_path=behavior_file_path, + fiber_photometry_folder_path=fiber_photometry_folder_path, + second_fiber_photometry_folder_path=second_fiber_photometry_folder_path, + fiber_photometry_t2=fiber_photometry_t2, + has_demodulated_commanded_voltages=False, + subject_id=subject_id, + session_conditions=session_conditions, + start_variable=start_variable, + start_datetime=start_datetime, + experiment_type=experiment_type, + experimental_group=experimental_group, + stub_test=stub_test, + ) # Fiber Photometry session with swapped left and right TTLs and missing Fi1d experiment_type = "FP" From 954e41e3af38169cebbff7e1cb2faa06b917b875 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 14:02:45 -0700 Subject: [PATCH 05/25] added experiment description and session description --- frozen_dependencies.txt | 2 +- .../seiler_2024_convert_session.py | 1 + .../seiler_2024/seiler_2024_metadata.yaml | 2 +- .../seiler_2024behaviorinterface.py | 34 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/frozen_dependencies.txt b/frozen_dependencies.txt index 2b75166..2de54f6 100644 --- a/frozen_dependencies.txt +++ b/frozen_dependencies.txt @@ -97,7 +97,7 @@ neuroconv==0.4.7 nodeenv==1.8.0 numcodecs==0.11.0 numpy==1.26.3 -nwbinspector==0.4.33 +nwbinspector==0.4.35 nwbwidgets==0.11.3 openpyxl==3.1.2 packaging==23.2 diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py index 2e90325..f79bbd2 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py @@ -154,6 +154,7 @@ def session_to_nwb( editable_metadata = load_dict_from_file(editable_metadata_path) metadata = dict_deep_update(metadata, editable_metadata) + metadata["NWBFile"]["session_description"] = metadata["Behavior"]["session_description"] session_start_time = metadata["NWBFile"]["session_start_time"] if optogenetic_treatment is None: session_id = f"{experiment_type}_{experimental_group}_{session_start_time.isoformat().replace(':', '-')}" diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml index 98c118b..ab6a210 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml @@ -1,7 +1,7 @@ NWBFile: related_publications: - https://doi.org/10.1016/j.cub.2022.01.055 - session_description: + experiment_description: Compulsive behavior is a defining feature of disorders such as substance use disorders. Current evidence suggests that corticostriatal circuits control the expression of established compulsions, but little is known about the mechanisms regulating the development of compulsions. diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index c695ebc..3cb454f 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -44,6 +44,39 @@ def __init__(self, file_path: str, session_conditions: dict, start_variable: str ) def get_metadata(self) -> DeepDict: + msn_to_session_description = { + "20sOmissions_TTL": "Omission Probe with concurrent fiber photometry", + "20sOmissions": "Omission Probe", + "FOOD_FR1 Habit Training TTL": "FR1 Habit Training with concurrent fiber photometry", + "FOOD_FR1 HT TTL (Both)": "FR1 Habit Training with concurrent fiber photometry, rewards delivered on both left and right nose pokes", + "FOOD_FR1 TTL Left": "FR1 Training with concurrent fiber photometry, rewards delivered on left nose pokes", + "FOOD_FR1 TTL Right": "FR1 Training with concurrent fiber photometry, rewards delivered on right nose pokes", + "FOOD_RI 30 LEFT": "RI30 Training, rewards delivered on left nose pokes", + "FOOD_RI 30 RIGHT TTL": "RI30 Training with concurrent fiber photometry, rewards delivered on right nose pokes", + "FOOD_RI 60 LEFT TTL": "RI60 Training with concurrent fiber photometry, rewards delivered on left nose pokes", + "FOOD_RI 60 RIGHT TTL": "RI60 Training with concurrent fiber photometry, rewards delivered on right nose pokes", + "Footshock Degradation Left": "Footshock Probe, shocks delivered on left nose pokes", + "Footshock Degradation right": "Footshock Probe, shocks delivered on right nose pokes", + "FR1_BOTH_SCRAMBLED": "FR1 Training with optogenetic stimulation, rewards delivered on both left and right nose pokes, optogenetic stimulation delivered on random nose pokes", + "FR1_BOTH_WStim": "FR1 Training with optogenetic stimulation, rewards delivered on both left and right nose pokes, optogenetic stimulation delivered on all nose pokes", + "FR1_LEFT_SCRAM": "FR1 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on random nose pokes", + "FR1_LEFT_STIM": "FR1 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on left nose pokes", + "FR1_RIGHT_SCRAMBLED": "FR1 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on random nose pokes", + "FR1_RIGHT_STIM": "FR1 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on right nose pokes", + "Probe Test Habit Training TTL": "Probe Test", + "RI 30 RIGHT_STIM": "RI30 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on right nose pokes", + "RI 60 RIGHT STIM": "RI60 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on right nose pokes", + "RI 60 LEFT_STIM": "RI60 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on left nose pokes", + "RI 30 LEFT_STIM": "RI30 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on left nose pokes", + "RI30 Left Scrambled": "RI30 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on random nose pokes", + "RI30 Right SCRAMBLED": "RI30 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on random nose pokes", + "RI60_LEFT_SCRAM": "RI60 Training with optogenetic stimulation, rewards delivered on left nose pokes, optogenetic stimulation delivered on random nose pokes", + "RI60_RIGHT_SCRAM": "RI60 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on random nose pokes", + "RR5_Left_CVC": "RR5 Training", + "RR20Left": "RR20 Training, rewards delivered on left nose pokes", + "RR20Right": "RR20 Training, rewards delivered on right nose pokes", + "Unknown": "Unknown", + } metadata = super().get_metadata() medpc_name_to_dict_name = { "Start Date": "start_date", @@ -100,6 +133,7 @@ def get_metadata(self) -> DeepDict: metadata["Behavior"] = {} metadata["Behavior"]["box"] = box metadata["Behavior"]["msn"] = msn + metadata["Behavior"]["session_description"] = msn_to_session_description[msn] return metadata From ef77bbd3c4920abf6d8835b40132d60462cb31c8 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 15:17:06 -0700 Subject: [PATCH 06/25] added keywords --- .../seiler_2024/seiler_2024_metadata.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml index ab6a210..ab8b152 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml @@ -23,6 +23,17 @@ NWBFile: - Bianco, Joseph M. - Bridgemohan, Abigael S. - Lerner, Talia N. + keywords: + - dorsal striatum + - dopamine + - substantia nigra + - reward learning + - habit formation + - compulsive behavior + - punishment-resistant reward seeking + - fiber photometry + - optogenetics + Subject: species: Mus musculus age: P10W/ # in ISO 8601, such as "P1W2D" From d82340d3d3d2f2c6fbbc52b4bf94954c6f90a08c Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 15:44:56 -0700 Subject: [PATCH 07/25] added question about non-ascending reward port entry/exit --- src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 387e533..6de0926 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -48,6 +48,11 @@ In FP Experiments/Behavior/PS/140.306, - one of the sessions (ex. 09/06/19) has a bunch of garbage to the right of the 'A' variable - Solution: Handled by reader +### Active Questions +- In FP Experiments/Behavior/RR20/95.259/95.259, some of the sessions (ex. 04/09/19) have non-ascending reward port intervals +ex. reward port entry = 985.750, reward port exit = 985.850 (duration = 0.1), next reward port entry = 985.800 (before previous exit) +how is this possible? + ### Resolved Questions In FP Experiments/Behavior/PS/139.298, - one of the sessions (ex. 09/20/19) is actually from subject 144.306 From 57278d7230a9f1b2697f985f816f4ed10459ba42 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 17:55:48 -0700 Subject: [PATCH 08/25] added explicit starting_time --- .../seiler_2024/seiler_2024fiberphotometryinterface.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index d064657..92b8647 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -208,6 +208,7 @@ def add_to_nwbfile( data=H5DataIO(tdt_photometry.streams["Fi1d"].data[0, :], compression=True), unit="volts", frequency=211.0, + starting_time=0.0, rate=tdt_photometry.streams["Fi1d"].fs, ) dms_commanded_reference_series = CommandedVoltageSeries( @@ -215,6 +216,7 @@ def add_to_nwbfile( data=H5DataIO(tdt_photometry.streams["Fi1d"].data[1, :], compression=True), unit="volts", frequency=330.0, + starting_time=0.0, rate=tdt_photometry.streams["Fi1d"].fs, ) dls_commanded_signal_series = CommandedVoltageSeries( @@ -222,6 +224,7 @@ def add_to_nwbfile( data=H5DataIO(tdt_photometry.streams["Fi1d"].data[3, :], compression=True), unit="volts", frequency=450.0, + starting_time=0.0, rate=tdt_photometry.streams["Fi1d"].fs, ) dls_commanded_reference_series = CommandedVoltageSeries( @@ -229,6 +232,7 @@ def add_to_nwbfile( data=H5DataIO(tdt_photometry.streams["Fi1d"].data[2, :], compression=True), unit="volts", frequency=270.0, + starting_time=0.0, rate=tdt_photometry.streams["Fi1d"].fs, ) else: @@ -236,12 +240,14 @@ def add_to_nwbfile( name="dms_commanded_voltage", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[0, :], compression=True), unit="volts", + starting_time=0.0, rate=tdt_photometry.streams["Fi1r"].fs, ) dls_commanded_voltage_series = CommandedVoltageSeries( name="dls_commanded_voltage", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[1, :], compression=True), unit="volts", + starting_time=0.0, rate=tdt_photometry.streams["Fi1r"].fs, ) @@ -371,6 +377,7 @@ def add_to_nwbfile( description="The fluorescence from the blue light excitation (465nm) corresponding to the calcium signal in the DMS.", data=H5DataIO(tdt_photometry.streams["Dv1A"].data, compression=True), unit="a.u.", + starting_time=0.0, rate=tdt_photometry.streams["Dv1A"].fs, fiber_photometry_table_region=dms_signal_region, ) @@ -379,6 +386,7 @@ def add_to_nwbfile( description="The fluorescence from the UV light excitation (405nm) corresponding to the isosbestic reference in the DMS.", data=H5DataIO(tdt_photometry.streams["Dv2A"].data, compression=True), unit="a.u.", + starting_time=0.0, rate=tdt_photometry.streams["Dv2A"].fs, fiber_photometry_table_region=dms_reference_region, ) @@ -387,6 +395,7 @@ def add_to_nwbfile( description="The fluorescence from the blue light excitation (465nm) corresponding to the calcium signal in the DLS.", data=H5DataIO(tdt_photometry.streams["Dv3B"].data, compression=True), unit="a.u.", + starting_time=0.0, rate=tdt_photometry.streams["Dv3B"].fs, fiber_photometry_table_region=dls_signal_region, ) @@ -395,6 +404,7 @@ def add_to_nwbfile( description="The fluorescence from the UV light excitation (405nm) corresponding to the isosbestic reference in the DLS.", data=H5DataIO(tdt_photometry.streams["Dv4B"].data, compression=True), unit="a.u.", + starting_time=0.0, rate=tdt_photometry.streams["Dv4B"].fs, fiber_photometry_table_region=dls_reference_region, ) From aa913e891d3e01b74a947689bd4efc71f94c84f9 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 18:07:11 -0700 Subject: [PATCH 09/25] omit empty left/right nose pokes --- .../seiler_2024behaviorinterface.py | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index 3cb454f..90dcbb7 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -230,18 +230,20 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict) -> None: behavior_module.add(behavioral_epochs) # Left/Right Nose pokes - left_nose_poke_times = Events( - name="left_nose_poke_times", - description="Left nose poke times", - timestamps=H5DataIO(session_dict["left_nose_poke_times"], compression=True), - ) - right_nose_poke_times = Events( - name="right_nose_poke_times", - description="Right nose poke times", - timestamps=H5DataIO(session_dict["right_nose_poke_times"], compression=True), - ) - behavior_module.add(left_nose_poke_times) - behavior_module.add(right_nose_poke_times) + if len(session_dict["left_nose_poke_times"]) > 0: + left_nose_poke_times = Events( + name="left_nose_poke_times", + description="Left nose poke times", + timestamps=H5DataIO(session_dict["left_nose_poke_times"], compression=True), + ) + behavior_module.add(left_nose_poke_times) + if len(session_dict["right_nose_poke_times"]) > 0: + right_nose_poke_times = Events( + name="right_nose_poke_times", + description="Right nose poke times", + timestamps=H5DataIO(session_dict["right_nose_poke_times"], compression=True), + ) + behavior_module.add(right_nose_poke_times) # Left/Right Rewards -- Interleaved for most sessions if len(session_dict["left_reward_times"]) > 0: From 19afd72e6f6e55163852665e7f766bd6c60bd973 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 18:17:19 -0700 Subject: [PATCH 10/25] added descriptions to commanded voltages --- .../seiler_2024/seiler_2024fiberphotometryinterface.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index 92b8647..9f21cea 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -205,6 +205,7 @@ def add_to_nwbfile( if has_demodulated_commanded_voltages: dms_commanded_signal_series = CommandedVoltageSeries( name="dms_commanded_signal", + description="The commanded voltage for the DMS signal.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[0, :], compression=True), unit="volts", frequency=211.0, @@ -213,6 +214,7 @@ def add_to_nwbfile( ) dms_commanded_reference_series = CommandedVoltageSeries( name="dms_commanded_reference", + description="The commanded voltage for the DMS isosbestic reference.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[1, :], compression=True), unit="volts", frequency=330.0, @@ -221,6 +223,7 @@ def add_to_nwbfile( ) dls_commanded_signal_series = CommandedVoltageSeries( name="dls_commanded_signal", + description="The commanded voltage for the DLS signal.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[3, :], compression=True), unit="volts", frequency=450.0, @@ -238,6 +241,7 @@ def add_to_nwbfile( else: dms_commanded_voltage_series = CommandedVoltageSeries( name="dms_commanded_voltage", + description="The modulated commanded voltage for the DMS (both signal and isosbestic).", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[0, :], compression=True), unit="volts", starting_time=0.0, @@ -245,6 +249,7 @@ def add_to_nwbfile( ) dls_commanded_voltage_series = CommandedVoltageSeries( name="dls_commanded_voltage", + description="The modulated commanded voltage for the DLS (both signal and isosbestic).", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[1, :], compression=True), unit="volts", starting_time=0.0, From 68aed4df704051778a680c73b1b910bf544a1e2c Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 18:47:16 -0700 Subject: [PATCH 11/25] fixed bug with get_ttl_timestamps --- src/lerner_lab_to_nwb/seiler_2024/seiler_2024nwbconverter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024nwbconverter.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024nwbconverter.py index 566016f..7b3617d 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024nwbconverter.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024nwbconverter.py @@ -117,10 +117,10 @@ def temporally_align_data_interfaces(self, metadata: dict, conversion_options: d def get_ttl_timestamps(self, ttl_name, tdt_photometry): if ttl_name == "PrtN": ttl_timestamps = [] - if "PrtN" in tdt_photometry.epocs: + if "PrtN" in tdt_photometry.epocs.keys(): for timestamp in tdt_photometry.epocs["PrtN"].onset: ttl_timestamps.append(timestamp) - if "PrtR" in tdt_photometry.epocs: + if "PrtR" in tdt_photometry.epocs.keys(): for timestamp in tdt_photometry.epocs["PrtR"].onset: ttl_timestamps.append(timestamp) ttl_timestamps = np.sort(ttl_timestamps) From 3be01814d2c7d3b47da14855ecfd208cd071dbb2 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 6 May 2024 18:57:00 -0700 Subject: [PATCH 12/25] added descriptions to commanded voltages --- .../seiler_2024/seiler_2024fiberphotometryinterface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index 9f21cea..3a40c5e 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -232,6 +232,7 @@ def add_to_nwbfile( ) dls_commanded_reference_series = CommandedVoltageSeries( name="dls_commanded_reference", + description="The commanded voltage for the DLS isosbestic reference.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[2, :], compression=True), unit="volts", frequency=270.0, From c31ee80e8a171a43d36023658177dd0f0a492f6a Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 10:18:16 -0700 Subject: [PATCH 13/25] added checks for empty footshock_times and port_entries --- .../seiler_2024/seiler_2024behaviorinterface.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index 90dcbb7..181f510 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -204,12 +204,13 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict) -> None: ): # some sessions are missing port entry durations ex. FP Experiments/Behavior/PR/028.392/07-09-20 if self.verbose: print(f"No port entry durations found for {metadata['NWBFile']['session_id']}") - reward_port_entry_times = Events( - name="reward_port_entry_times", - description="Reward port entry times", - timestamps=H5DataIO(session_dict["port_entry_times"], compression=True), - ) - behavior_module.add(reward_port_entry_times) + if len(session_dict["port_entry_times"]) > 0: + reward_port_entry_times = Events( + name="reward_port_entry_times", + description="Reward port entry times", + timestamps=H5DataIO(session_dict["port_entry_times"], compression=True), + ) + behavior_module.add(reward_port_entry_times) else: port_times, data = [], [] for port_entry_time, duration in zip( @@ -262,7 +263,7 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict) -> None: behavior_module.add(right_reward_times) # Footshock - if "footshock_times" in session_dict: + if "footshock_times" in session_dict and len(session_dict["footshock_times"]) > 0: footshock_times = Events( name="footshock_times", description="Footshock times", From 5dac5d95ff1817d437a41615df4466ba21583350 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 10:30:39 -0700 Subject: [PATCH 14/25] added note about doric lenses dichroic --- .../seiler_2024/seiler_2024fiberphotometryinterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index 3a40c5e..1710f1a 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -176,7 +176,7 @@ def add_to_nwbfile( ) # Dichroic Mirror - dichroic_mirror = DichroicMirror( # TODO: Get characteristic wavelengths from Doric Lenses + dichroic_mirror = DichroicMirror( # Doric Lenses can not provide characteristic wavelengths for this product name="dichroic_mirror", description="Dual excitation band fiber photometry measurements use a Fluorescence Mini Cube with 4 ports: one port for the functional fluorescence excitation light, one for the isosbestic excitation, one for the fluorescence detection, and one for the sample. The cube has dichroic mirrors to combine isosbestic and fluorescence excitations and separate the fluorescence emission and narrow bandpass filters limiting the excitation fluorescence spectrum.", manufacturer="Doric Lenses", From 305b2cf32e916b069c683d17f0e31797c117cfe0 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 10:58:53 -0700 Subject: [PATCH 15/25] added session_should_be_skipped logic to fp --- .../seiler_2024/seiler_2024_convert_dataset.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 782203b..304bf1e 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -226,13 +226,8 @@ def fp_to_nwb( for start_date, start_time, msn, file, subject, box_number in zip( start_dates, start_times, msns, file_paths, subjects, box_numbers ): - if ( - photometry_subject_id == "271.396" - and photometry_start_date == "07/07/20" - and msn == "FOOD_RI 60 RIGHT TTL" - or photometry_subject_id == "88.239" - and photometry_start_date == "02/19/19" - and msn == "FOOD_RI 60 LEFT TTL" + if session_should_be_skipped( + start_date=start_date, start_time=start_time, subject_id=photometry_subject_id, msn=msn ): continue if start_date == photometry_start_date: @@ -781,6 +776,8 @@ def session_should_be_skipped(*, start_date, start_time, subject_id, msn): and subject_id == "346.394" and msn == "FOOD_RI 60 RIGHT TTL" ) + or (subject_id == "271.396" and start_date == "07/07/20" and msn == "FOOD_RI 60 RIGHT TTL") + or (subject_id == "88.239" and start_date == "02/19/19" and msn == "FOOD_RI 60 LEFT TTL") ): return True return False From 90e1a7c4f296bdeab2f544c25a889db52b87b8ac Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 11:19:49 -0700 Subject: [PATCH 16/25] UNDO session_should_be_skipped logic to fp --- .../seiler_2024/seiler_2024_convert_dataset.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 304bf1e..782203b 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -226,8 +226,13 @@ def fp_to_nwb( for start_date, start_time, msn, file, subject, box_number in zip( start_dates, start_times, msns, file_paths, subjects, box_numbers ): - if session_should_be_skipped( - start_date=start_date, start_time=start_time, subject_id=photometry_subject_id, msn=msn + if ( + photometry_subject_id == "271.396" + and photometry_start_date == "07/07/20" + and msn == "FOOD_RI 60 RIGHT TTL" + or photometry_subject_id == "88.239" + and photometry_start_date == "02/19/19" + and msn == "FOOD_RI 60 LEFT TTL" ): continue if start_date == photometry_start_date: @@ -776,8 +781,6 @@ def session_should_be_skipped(*, start_date, start_time, subject_id, msn): and subject_id == "346.394" and msn == "FOOD_RI 60 RIGHT TTL" ) - or (subject_id == "271.396" and start_date == "07/07/20" and msn == "FOOD_RI 60 RIGHT TTL") - or (subject_id == "88.239" and start_date == "02/19/19" and msn == "FOOD_RI 60 LEFT TTL") ): return True return False From b2e28f1af9dc5e1e689719fe9f18cc46dffcafa4 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 11:32:45 -0700 Subject: [PATCH 17/25] debugging nwbinspector errors --- .../seiler_2024_convert_session.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py index f79bbd2..c621f55 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py @@ -165,6 +165,42 @@ def session_to_nwb( metadata["NWBFile"]["session_start_time"] = metadata["NWBFile"]["session_start_time"].replace(tzinfo=cst) nwbfile_path = output_dir_path / f"sub-{subject_id}_ses-{session_id}.nwb" + nwbinspector_error_file_paths = [ + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-64.205_ses-FP_DPR_2018-10-18T09-29-02.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-111.285_ses-FP_PR_2019-06-27T10-27-42.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-141.308_ses-FP_PR_2019-09-06T09-11-16.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-110.271_ses-FP_PS_2019-06-27T09-53-23.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-112.283_ses-FP_PS_2019-06-27T08-56-16.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-113.283_ses-FP_PS_2019-06-27T09-27-18.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-114.273_ses-FP_PS_2019-07-02T12-40-22.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-139.298_ses-FP_PS_2019-09-17T10-17-42.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-140.306_ses-FP_PS_2019-09-06T09-11-16.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-242.388_ses-Opto-DLS-Excitatory-ChR2-2020-07-30T11-17-58.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-313.403_ses-Opto-DLS-Excitatory-EYFP-2020-09-17T11-42-56.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-238.388_ses-Opto-DLS-Excitatory-EYFP-2020-07-31T11-56-32.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-344.400_ses-Opto-DLS-Excitatory-EYFP-2020-08-04T11-45-57.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-342.400_ses-Opto-DLS-Excitatory-EYFP-2020-07-30T11-53-15.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-417.404_ses-Opto-DLS-Excitatory-EYFP-2020-10-01T11-17-52.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-419.404_ses-Opto-DLS-Excitatory-EYFP-2020-10-01T11-17-52.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-239.388_ses-Opto-DLS-Excitatory-ChR2Scrambled-2020-07-31T11-56-32.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-281.402_ses-Opto-DMS-Excitatory-ChR2-2020-10-27T11-43-22.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-448.419_ses-Opto-DMS-Excitatory-ChR2-2020-12-08T11-43-00.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-429.419_ses-Opto-DMS-Excitatory-ChR2-2020-11-28T11-50-24.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-129.425_ses-Opto-DMS-Excitatory-EYFP-2020-12-04T12-44-14.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-116.417_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-12-03T12-21-24.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-130.425_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-12-05T12-33-43.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-282.402_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-10-27T11-43-22.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-450.417_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-11-28T11-01-52.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-436.422_ses-Opto-DMS-Inhibitory-NpHR-2020-12-01T13-12-08.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-430.420_ses-Opto-DMS-Inhibitory-NpHR-2020-12-08T11-43-00.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-266.477_ses-Opto-DMS-Inhibitory-NpHR-2021-11-16T10-19-57.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-263.477_ses-Opto-DMS-Inhibitory-EYFP-2021-11-04T11-53-19.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-267.476_ses-Opto-DMS-Inhibitory-EYFP-2021-11-11T12-07-09.nwb", + "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-260.478_ses-Opto-DMS-Inhibitory-NpHRScrambled-2021-11-16T10-53-48.nwb", + ] + if str(nwbfile_path) not in nwbinspector_error_file_paths: + return + # Run conversion converter.run_conversion(metadata=metadata, nwbfile_path=nwbfile_path, conversion_options=conversion_options) From a7851334c7e513bb50dadc5bc7f2bbcd8ef77151 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 11:33:10 -0700 Subject: [PATCH 18/25] added RR20_Left and RR20_Right_AHJS --- .../seiler_2024/seiler_2024_convert_dataset.py | 2 -- .../seiler_2024/seiler_2024_metadata.yaml | 16 ++++++++++++++++ .../seiler_2024/seiler_2024_notes.md | 3 ++- .../seiler_2024fiberphotometryinterface.py | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 782203b..1eea755 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -750,8 +750,6 @@ def session_should_be_skipped(*, start_date, start_time, subject_id, msn): "FOOD_Magazine Training 1 hr", "RI_60_Left_Probability_AH_050619", "RI_60_Right_Probability_AH_050619", - "RR20_Right_AHJS", - "RR20_Left", "Extinction - 1 HR", "RR10_Left_AHJS", "Probe Test Habit Training CC", diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml index ab8b152..ca0f876 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_metadata.yaml @@ -263,6 +263,14 @@ Behavior: E: duration_of_port_entry G: port_entry_times H: footshock_times + RR20_Left: + A: left_nose_poke_times + B: left_reward_times + C: right_nose_poke_times + D: right_reward_times + E: duration_of_port_entry + G: port_entry_times + H: footshock_times RR20Right: A: left_nose_poke_times B: left_reward_times @@ -271,6 +279,14 @@ Behavior: E: duration_of_port_entry G: port_entry_times H: footshock_times + RR20_Right_AHJS: + A: left_nose_poke_times + B: left_reward_times + C: right_nose_poke_times + D: right_reward_times + E: duration_of_port_entry + G: port_entry_times + H: footshock_times Optogenetics: experimental_group_to_metadata: diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 6de0926..34cc9f1 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -127,7 +127,8 @@ for that 1 session split across the two folders? - Skip this session bc Lerner Lab can't find it ### Active Questions -None +- Some fiber photometry sessions (ex. FP_RR20_96.259_2019-04-17T16-03-52) have msns that I was told to skip (ex. RR20_Right_AHJS) + Should I still skip these, or just treat them like RR20Right? ## Optogenetics ### Notes diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index 1710f1a..3a40c5e 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -176,7 +176,7 @@ def add_to_nwbfile( ) # Dichroic Mirror - dichroic_mirror = DichroicMirror( # Doric Lenses can not provide characteristic wavelengths for this product + dichroic_mirror = DichroicMirror( # TODO: Get characteristic wavelengths from Doric Lenses name="dichroic_mirror", description="Dual excitation band fiber photometry measurements use a Fluorescence Mini Cube with 4 ports: one port for the functional fluorescence excitation light, one for the isosbestic excitation, one for the fluorescence detection, and one for the sample. The cube has dichroic mirrors to combine isosbestic and fluorescence excitations and separate the fluorescence emission and narrow bandpass filters limiting the excitation fluorescence spectrum.", manufacturer="Doric Lenses", From 3a3b9c01fde46f44d18599c37d141008ce7628ac Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 11:35:35 -0700 Subject: [PATCH 19/25] added RR20_Left and RR20_Right_AHJS --- .../seiler_2024/seiler_2024behaviorinterface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index 181f510..351800a 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -74,7 +74,9 @@ def get_metadata(self) -> DeepDict: "RI60_RIGHT_SCRAM": "RI60 Training with optogenetic stimulation, rewards delivered on right nose pokes, optogenetic stimulation delivered on random nose pokes", "RR5_Left_CVC": "RR5 Training", "RR20Left": "RR20 Training, rewards delivered on left nose pokes", + "RR20_Left": "RR20 Training, rewards delivered on left nose pokes", "RR20Right": "RR20 Training, rewards delivered on right nose pokes", + "RR20_Right_AHJS": "RR20 Training, rewards delivered on right nose pokes", "Unknown": "Unknown", } metadata = super().get_metadata() From 21b3ba25069de56a71090899595a7ad7758081bf Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 12:52:45 -0700 Subject: [PATCH 20/25] skip empty port entries --- .../seiler_2024/seiler_2024behaviorinterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index 351800a..6e9b758 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -213,7 +213,7 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict) -> None: timestamps=H5DataIO(session_dict["port_entry_times"], compression=True), ) behavior_module.add(reward_port_entry_times) - else: + elif len(session_dict["port_entry_times"]) > 0: port_times, data = [], [] for port_entry_time, duration in zip( session_dict["port_entry_times"], session_dict["duration_of_port_entry"] From f70edd000bc8c57e49b717b32a4eff44df4596ee Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 13:40:24 -0700 Subject: [PATCH 21/25] remove debug --- .../seiler_2024_convert_session.py | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py index c621f55..f79bbd2 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_session.py @@ -165,42 +165,6 @@ def session_to_nwb( metadata["NWBFile"]["session_start_time"] = metadata["NWBFile"]["session_start_time"].replace(tzinfo=cst) nwbfile_path = output_dir_path / f"sub-{subject_id}_ses-{session_id}.nwb" - nwbinspector_error_file_paths = [ - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-64.205_ses-FP_DPR_2018-10-18T09-29-02.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-111.285_ses-FP_PR_2019-06-27T10-27-42.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-141.308_ses-FP_PR_2019-09-06T09-11-16.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-110.271_ses-FP_PS_2019-06-27T09-53-23.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-112.283_ses-FP_PS_2019-06-27T08-56-16.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-113.283_ses-FP_PS_2019-06-27T09-27-18.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-114.273_ses-FP_PS_2019-07-02T12-40-22.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-139.298_ses-FP_PS_2019-09-17T10-17-42.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-140.306_ses-FP_PS_2019-09-06T09-11-16.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-242.388_ses-Opto-DLS-Excitatory-ChR2-2020-07-30T11-17-58.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-313.403_ses-Opto-DLS-Excitatory-EYFP-2020-09-17T11-42-56.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-238.388_ses-Opto-DLS-Excitatory-EYFP-2020-07-31T11-56-32.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-344.400_ses-Opto-DLS-Excitatory-EYFP-2020-08-04T11-45-57.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-342.400_ses-Opto-DLS-Excitatory-EYFP-2020-07-30T11-53-15.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-417.404_ses-Opto-DLS-Excitatory-EYFP-2020-10-01T11-17-52.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-419.404_ses-Opto-DLS-Excitatory-EYFP-2020-10-01T11-17-52.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-239.388_ses-Opto-DLS-Excitatory-ChR2Scrambled-2020-07-31T11-56-32.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-281.402_ses-Opto-DMS-Excitatory-ChR2-2020-10-27T11-43-22.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-448.419_ses-Opto-DMS-Excitatory-ChR2-2020-12-08T11-43-00.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-429.419_ses-Opto-DMS-Excitatory-ChR2-2020-11-28T11-50-24.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-129.425_ses-Opto-DMS-Excitatory-EYFP-2020-12-04T12-44-14.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-116.417_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-12-03T12-21-24.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-130.425_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-12-05T12-33-43.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-282.402_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-10-27T11-43-22.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-450.417_ses-Opto-DMS-Excitatory-ChR2Scrambled-2020-11-28T11-01-52.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-436.422_ses-Opto-DMS-Inhibitory-NpHR-2020-12-01T13-12-08.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-430.420_ses-Opto-DMS-Inhibitory-NpHR-2020-12-08T11-43-00.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-266.477_ses-Opto-DMS-Inhibitory-NpHR-2021-11-16T10-19-57.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-263.477_ses-Opto-DMS-Inhibitory-EYFP-2021-11-04T11-53-19.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-267.476_ses-Opto-DMS-Inhibitory-EYFP-2021-11-11T12-07-09.nwb", - "/Volumes/T7/CatalystNeuro/NWB/Lerner/conversion_nwb/sub-260.478_ses-Opto-DMS-Inhibitory-NpHRScrambled-2021-11-16T10-53-48.nwb", - ] - if str(nwbfile_path) not in nwbinspector_error_file_paths: - return - # Run conversion converter.run_conversion(metadata=metadata, nwbfile_path=nwbfile_path, conversion_options=conversion_options) From 2d3d793d6fa458c6505e89363e7e83565e2f09b6 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 16:53:50 -0700 Subject: [PATCH 22/25] added some extra fi1r_only sessions --- .../seiler_2024/seiler_2024_convert_dataset.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 1eea755..24f86a3 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -185,6 +185,15 @@ def fp_to_nwb( "Photo_89_247-190308-095258", "Photo_140_306-190809-121107", "Photo_271_396-200707-125117", + "Photo_96_259-190417-160333", + "Photo_97_257-190417-134643", + "Photo_97_257-190506-120133", + "Photo_98_257-190424-114024", + "Photo_98_257-190510-095056", + "Photo_99_257-190506-130951", + "Photo_100_258-190423-122632", + "Photo_100_258-190509-133212", + "Photo_101_260-190425-120029", } raw_file_to_info = get_raw_info(behavior_path) From 2a0044cf5cfc20caf266f868fcfa8b67c77dffe3 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 17:09:32 -0700 Subject: [PATCH 23/25] skipped problematic session and added a note --- .../seiler_2024/seiler_2024_convert_dataset.py | 5 +++++ src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py index 24f86a3..8ac0cb3 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_convert_dataset.py @@ -300,6 +300,11 @@ def fp_to_nwb( and photometry_start_date == "10/31/18" and experimental_subgroup.name == "Late RI60" ) + or ( + photometry_subject_id == "96.259" + and photometry_start_date == "05/06/19" + and experimental_subgroup.name == "late" + ) # This session is missing RNnR TTLs ): continue assert ( diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md index 34cc9f1..1210bf5 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024_notes.md @@ -129,6 +129,8 @@ for that 1 session split across the two folders? ### Active Questions - Some fiber photometry sessions (ex. FP_RR20_96.259_2019-04-17T16-03-52) have msns that I was told to skip (ex. RR20_Right_AHJS) Should I still skip these, or just treat them like RR20Right? +- In one of those sessions, FP Experiments/Photometry/RR20/late/Photo_96_259-190506-105642, doesn't have any RNnR TTLs, + even though it has plenty of right nose pokes in the behavioral file. Can you look into this? ## Optogenetics ### Notes From 84c404fba25eafbd0ccedd2132ab42eeb139db6b Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Wed, 8 May 2024 18:55:30 -0700 Subject: [PATCH 24/25] added duration_of_port_entry from medpc files for fiber photometry sessions --- .../seiler_2024/seiler_2024behaviorinterface.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py index 6e9b758..b230da6 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024behaviorinterface.py @@ -188,6 +188,18 @@ def add_to_nwbfile(self, nwbfile: NWBFile, metadata: dict) -> None: session_dict[dict_name] = np.trim_zeros(session_df[csv_name].dropna().values, trim="b") else: session_dict = self.source_data["session_dict"] + msn = metadata["Behavior"]["msn"] + medpc_name_to_dict_name = metadata["Behavior"]["msn_to_medpc_name_to_dict_name"][msn] + dict_name_to_type = {dict_name: np.ndarray for dict_name in medpc_name_to_dict_name.values()} + medpc_session_dict = read_medpc_file( + file_path=self.source_data["file_path"], + medpc_name_to_dict_name=medpc_name_to_dict_name, + dict_name_to_type=dict_name_to_type, + session_conditions=self.source_data["session_conditions"], + start_variable=self.source_data["start_variable"], + ) + if "duration_of_port_entry" in medpc_session_dict: + session_dict["duration_of_port_entry"] = medpc_session_dict["duration_of_port_entry"] # Add behavior data to nwbfile behavior_module = nwb_helpers.get_module( From 74135bbf877ae3d6af593b81c4f1a90cade11130 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Tue, 28 May 2024 13:59:57 -0700 Subject: [PATCH 25/25] added commanded voltage descriptions --- frozen_dependencies.txt | 4 ++-- .../seiler_2024/seiler_2024fiberphotometryinterface.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frozen_dependencies.txt b/frozen_dependencies.txt index 4839da8..54c5faf 100644 --- a/frozen_dependencies.txt +++ b/frozen_dependencies.txt @@ -88,7 +88,7 @@ more-itertools==10.2.0 multidict==6.0.4 natsort==8.4.0 ndx-events==0.2.0 -ndx-fiber-photometry @ git+https://github.com/catalystneuro/ndx-fiber-photometry.git@14e05cda86026db694c1c577918284f435b7ec10 +ndx-fiber-photometry @ git+https://github.com/catalystneuro/ndx-fiber-photometry.git@94d80c2996cf3c71bd7e6f2b2c83f9b3fb9906ff ndx-grayscalevolume==0.0.2 ndx-icephys-meta==0.1.0 ndx-photometry @ git+https://github.com/catalystneuro/ndx-photometry.git@c1284c91a7e0a5dfd19f84bbf683e17fa607d4ec @@ -99,7 +99,7 @@ neuroconv @ git+https://github.com/catalystneuro/neuroconv.git@f45e77e1523699164 nodeenv==1.8.0 numcodecs==0.11.0 numpy==1.26.3 -nwbinspector==0.4.35 +-e git+https://github.com/catalystneuro/nwbinspector.git@1f88732833709fc194ec46ebb82b0427137a2825#egg=nwbinspector nwbwidgets==0.11.3 openpyxl==3.1.2 packaging==23.2 diff --git a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py index 8dcad61..fc8b631 100644 --- a/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py +++ b/src/lerner_lab_to_nwb/seiler_2024/seiler_2024fiberphotometryinterface.py @@ -182,6 +182,7 @@ def add_to_nwbfile( if has_demodulated_commanded_voltages: commanded_voltage_series_dms_calcium_signal = CommandedVoltageSeries( name="commanded_voltage_series_dms_calcium_signal", + description="The commanded voltage for the DMS calcium signal.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[0, :], compression=True), unit="volts", frequency=211.0, @@ -190,6 +191,7 @@ def add_to_nwbfile( ) commanded_voltage_series_dms_isosbestic_control = CommandedVoltageSeries( name="commanded_voltage_series_dms_isosbestic_control", + description="The commanded voltage for the DMS isosbestic control.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[1, :], compression=True), unit="volts", frequency=330.0, @@ -198,6 +200,7 @@ def add_to_nwbfile( ) commanded_voltage_series_dls_calcium_signal = CommandedVoltageSeries( name="commanded_voltage_series_dls_calcium_signal", + description="The commanded voltage for the DLS calcium signal.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[3, :], compression=True), unit="volts", frequency=450.0, @@ -206,6 +209,7 @@ def add_to_nwbfile( ) commanded_voltage_series_dls_isosbestic_control = CommandedVoltageSeries( name="commanded_voltage_series_dls_isosbestic_control", + description="The commanded voltage for the DLS isosbestic control.", data=H5DataIO(tdt_photometry.streams["Fi1d"].data[2, :], compression=True), unit="volts", frequency=270.0, @@ -215,6 +219,7 @@ def add_to_nwbfile( else: commanded_voltage_series_dms = CommandedVoltageSeries( name="commanded_voltage_series_dms", + description="The commanded voltage for the frequency-modulated DMS calcium signal and DMS isosbestic control.", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[0, :], compression=True), unit="volts", starting_time=0.0, @@ -222,6 +227,7 @@ def add_to_nwbfile( ) commanded_voltage_series_dls = CommandedVoltageSeries( name="commanded_voltage_series_dls", + description="The commanded voltage for the frequency-modulated DLS calcium signal and DLS isosbestic control.", data=H5DataIO(tdt_photometry.streams["Fi1r"].data[1, :], compression=True), unit="volts", starting_time=0.0,