From 6311399a46ae69464ee0ee485c658c71e33bfd6f Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 19 Oct 2026 10:36:03 -0700 Subject: [PATCH 1/3] Convert mouse 262.478 and fix the institution name Co-Authored-By: Claude Opus 5.5 --- notebooks/subject_labels.ipynb | 479 ++++++++++++++++++ .../seiler_2024_convert_dataset.py | 38 +- .../seiler_2024/seiler_2024_metadata.yaml | 2 +- .../seiler_2024/seiler_2024_notes.md | 3 +- tests/test_subject_labels.py | 22 + 5 files changed, 523 insertions(+), 21 deletions(-) create mode 100644 notebooks/subject_labels.ipynb create mode 100644 tests/test_subject_labels.py diff --git a/notebooks/subject_labels.ipynb b/notebooks/subject_labels.ipynb new file mode 100644 index 0000000..3b632c8 --- /dev/null +++ b/notebooks/subject_labels.ipynb @@ -0,0 +1,479 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3c282cee", + "metadata": {}, + "source": [ + "# Mouse 262.478 and the institution name\n", + "\n", + "Every raw file and `Subject:` field for this DMS Inhibitory Group 2 mouse reads `262` or `262.478`. Only the file name `2021-10-29_262_259.478`, which also has a copy in `Scrambled`, reads 262.259. The demographics sheet originally listed 262.478; in May 2024 the conversion's copy of the sheet was changed to 262.259 to match that one file name, which made 262.478 \"missing\" and dropped the mouse's other sessions. DANDI:000971 holds only the Scrambled copy of the 10/29 run, labeled NpHRScrambled.\n", + "\n", + "With the sheet row set back to 262.478, this notebook converts the mouse's sessions and compares the 10/29 run with the published file. It also shows the institution name, which was misspelled in every published file." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "32be112c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-10-19T17:35:21.064513Z", + "iopub.status.busy": "2026-10-19T17:35:21.064303Z", + "iopub.status.idle": "2026-10-19T17:35:23.569079Z", + "shell.execute_reply": "2026-10-19T17:35:23.568623Z" + } + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import shutil\n", + "\n", + "import h5py\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_dataset import (\n", + " SUBJECTS_TO_SKIP,\n", + " opto_to_nwb,\n", + " get_no_port_entry_duration_sessions,\n", + " get_session_key_from_kwargs,\n", + ")\n", + "from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_session import session_to_nwb\n", + "\n", + "data_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/_Raw_Data_for_future_reference\")\n", + "published_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/000971\")\n", + "output_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/fix_audit/subject_labels\")\n", + "if output_dir_path.exists():\n", + " shutil.rmtree(output_dir_path)\n", + "output_dir_path.mkdir(parents=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a6c63054", + "metadata": { + "execution": { + "iopub.execute_input": "2026-10-19T17:35:23.570947Z", + "iopub.status.busy": "2026-10-19T17:35:23.570732Z", + "iopub.status.idle": "2026-10-19T17:35:23.765237Z", + "shell.execute_reply": "2026-10-19T17:35:23.764929Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Mouse IDExperimentSexTreatment
149262.478DMS Inhibitory Group 2MaleInhibitory stimulation on rewarded nosepokes (...
\n", + "
" + ], + "text/plain": [ + " Mouse ID Experiment Sex \\\n", + "149 262.478 DMS Inhibitory Group 2 Male \n", + "\n", + " Treatment \n", + "149 Inhibitory stimulation on rewarded nosepokes (... " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "demographics = pd.read_excel(data_dir_path / \"MouseDemographicsCorrected.xlsx\", sheet_name=\"Mouse Demographics\", dtype={\"Mouse ID\": str})\n", + "demographics[demographics[\"Mouse ID\"].str.startswith(\"262\")][[\"Mouse ID\", \"Experiment\", \"Sex\", \"Treatment\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f9eb7635", + "metadata": { + "execution": { + "iopub.execute_input": "2026-10-19T17:35:23.766882Z", + "iopub.status.busy": "2026-10-19T17:35:23.766730Z", + "iopub.status.idle": "2026-10-19T17:35:26.368998Z", + "shell.execute_reply": "2026-10-19T17:35:26.368705Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
sessions
subject_idtreatmentfileskipped
262.478NpHRDMS Inhibitory/Group 2/NpHr/262.478False18
262.259NpHRScrambledDMS Inhibitory/Group 2/Scrambled/2021-10-29_262_259 - Copy.478True1
262.478NpHRDMS Inhibitory/Group 2/NpHr/2021-10-25_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-26_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-27_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-29_262_259.478False1
\n", + "
" + ], + "text/plain": [ + " sessions\n", + "subject_id treatment file skipped \n", + "262.478 NpHR DMS Inhibitory/Group 2/NpHr/262.478 False 18\n", + "262.259 NpHRScrambled DMS Inhibitory/Group 2/Scrambled/2021-10-29_262... True 1\n", + "262.478 NpHR DMS Inhibitory/Group 2/NpHr/2021-10-25_262.478 False 1\n", + " DMS Inhibitory/Group 2/NpHr/2021-10-26_262.478 False 1\n", + " DMS Inhibitory/Group 2/NpHr/2021-10-27_262.478 False 1\n", + " DMS Inhibitory/Group 2/NpHr/2021-10-29_262_259.478 False 1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session_to_nwb_kwargs_per_session = [\n", + " session_to_nwb_kwargs\n", + " for session_to_nwb_kwargs in opto_to_nwb(\n", + " data_dir_path=data_dir_path, output_dir_path=output_dir_path, start_variable=\"Start Date\", verbose=False\n", + " )\n", + " if session_to_nwb_kwargs[\"subject_id\"].startswith(\"262\")\n", + "]\n", + "pd.DataFrame(\n", + " [\n", + " dict(\n", + " subject_id=session_to_nwb_kwargs[\"subject_id\"],\n", + " treatment=session_to_nwb_kwargs[\"optogenetic_treatment\"],\n", + " file=session_to_nwb_kwargs[\"behavior_file_path\"].relative_to(data_dir_path / \"Opto Experiments\").as_posix(),\n", + " skipped=session_to_nwb_kwargs[\"subject_id\"] in SUBJECTS_TO_SKIP,\n", + " )\n", + " for session_to_nwb_kwargs in session_to_nwb_kwargs_per_session\n", + " ]\n", + ").value_counts().to_frame(\"sessions\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8b90a803", + "metadata": { + "execution": { + "iopub.execute_input": "2026-10-19T17:35:26.370472Z", + "iopub.status.busy": "2026-10-19T17:35:26.370354Z", + "iopub.status.idle": "2026-10-19T17:35:42.777986Z", + "shell.execute_reply": "2026-10-19T17:35:42.777699Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "Reading port entry durations: 0%| | 0/22 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
versionfilesubject_idsexstimulus_notesinstitution
0publishedsub-262-259_ses-Opto-DMS-Inhibitory-NpHRScramb...262.259MInhibitory stimulation on rewarded nosepokes (...Northwestern Unitersity
1fixedsub-262.478_ses-Opto-DMS-Inhibitory-NpHR-2021-...262.478MInhibitory stimulation on rewarded nosepokes (...Northwestern University
\n", + "" + ], + "text/plain": [ + " version file subject_id \\\n", + "0 published sub-262-259_ses-Opto-DMS-Inhibitory-NpHRScramb... 262.259 \n", + "1 fixed sub-262.478_ses-Opto-DMS-Inhibitory-NpHR-2021-... 262.478 \n", + "\n", + " sex stimulus_notes \\\n", + "0 M Inhibitory stimulation on rewarded nosepokes (... \n", + "1 M Inhibitory stimulation on rewarded nosepokes (... \n", + "\n", + " institution \n", + "0 Northwestern Unitersity \n", + "1 Northwestern University " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def summarize(file_path: Path) -> dict:\n", + " with h5py.File(file_path, \"r\") as file:\n", + " return dict(\n", + " file=file_path.name,\n", + " subject_id=file[\"general/subject/subject_id\"][()].decode(),\n", + " sex=file[\"general/subject/sex\"][()].decode(),\n", + " stimulus_notes=file[\"general/stimulus\"][()].decode(),\n", + " institution=file[\"general/institution\"][()].decode(),\n", + " )\n", + "\n", + "\n", + "def read_behavior_datasets(file_path: Path) -> dict[str, np.ndarray]:\n", + " datasets = {}\n", + " with h5py.File(file_path, \"r\") as file:\n", + " for group in (\"processing/behavior\", \"stimulus\"):\n", + " if group in file:\n", + " file[group].visititems(\n", + " lambda name, item: datasets.__setitem__(f\"{group}/{name}\", item[()]) if isinstance(item, h5py.Dataset) else None\n", + " )\n", + " return datasets\n", + "\n", + "\n", + "(published_file_path,) = (published_dir_path / \"sub-262-259\").glob(\"*.nwb\")\n", + "(new_file_path,) = output_dir_path.glob(\"*2021-10-29T15-11-08*.nwb\")\n", + "pd.DataFrame([dict(version=\"published\", **summarize(published_file_path)), dict(version=\"fixed\", **summarize(new_file_path))])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d022c2f1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-10-19T17:35:42.789336Z", + "iopub.status.busy": "2026-10-19T17:35:42.789256Z", + "iopub.status.idle": "2026-10-19T17:35:42.793832Z", + "shell.execute_reply": "2026-10-19T17:35:42.793578Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "same datasets: True\n", + "same values: True\n" + ] + } + ], + "source": [ + "published_datasets = read_behavior_datasets(published_file_path)\n", + "new_datasets = read_behavior_datasets(new_file_path)\n", + "print(\"same datasets:\", set(published_datasets) == set(new_datasets))\n", + "print(\"same values:\", all(np.array_equal(published_datasets[name], new_datasets[name]) for name in new_datasets))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "lerner_lab_to_nwb_env", + "language": "python", + "name": "lerner_lab_to_nwb_env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} 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 a38e1ca..a02a52e 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 @@ -54,6 +54,25 @@ from lerner_lab_to_nwb.seiler_2024.medpc_helpers import get_medpc_variables, read_medpc_file +SUBJECTS_TO_SKIP = { # subject IDs that are not in the demographics sheet + "289.407", + "244.464", + "264.477", + "264.478", + "102.260", + "262.259", # parsed from "Scrambled/2021-10-29_262_259 - Copy.478", a copy of 262.478's 10/29/21 run + "289.408", + "264.475", + "129.425", + "250.427", + "95.259", + "309.399", + "433.421", + "416.405", + "364.426", +} + + def dataset_to_nwb( *, data_dir_path: Union[str, Path], @@ -75,23 +94,6 @@ def dataset_to_nwb( verbose : bool, optional Whether to print verbose output, by default True """ - subjects_to_skip = { - "289.407", - "244.464", - "264.477", - "264.478", - "102.260", - "262.478", - "289.408", - "264.475", - "129.425", - "250.427", - "95.259", - "309.399", - "433.421", - "416.405", - "364.426", - } start_variable = "Start Date" data_dir_path = Path(data_dir_path) output_dir_path = Path(output_dir_path) @@ -122,7 +124,7 @@ def dataset_to_nwb( if session_key in no_port_entry_duration_sessions: session_to_nwb_kwargs["has_port_entry_durations"] = False subject_id = session_to_nwb_kwargs["subject_id"] - if subject_id in subjects_to_skip: + if subject_id in SUBJECTS_TO_SKIP: continue session_to_nwb_args_per_session.append(session_to_nwb_kwargs) 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 0e964af..f39b6a1 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 @@ -13,7 +13,7 @@ NWBFile: Amplifying this dopamine signal accelerated animals' transitions to compulsion, whereas inhibition delayed it. In contrast, amplifying DLS dopamine signaling had no effect on the emergence of compulsions. These results establish DMS dopamine signaling as a key controller of the development of compulsive reward seeking. - institution: Northwestern Unitersity + institution: Northwestern University lab: Lerner experimenter: - Seiler, Jillian L. 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 28e1c06..a076a6c 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 @@ -221,7 +221,6 @@ None 359.43 --> 359.430 28.392 --> 028.392 227.43 --> 227.430 - 262.478 --> 262.259 354.43 --> 354.430 430.42 --> 430.420 342.483 --> 342.400 @@ -231,7 +230,7 @@ None "244.464", "264.477", "102.260", - "262.478", + "262.259", "289.408", "264.475", "129.425", diff --git a/tests/test_subject_labels.py b/tests/test_subject_labels.py new file mode 100644 index 0000000..6783d0b --- /dev/null +++ b/tests/test_subject_labels.py @@ -0,0 +1,22 @@ +from pathlib import Path + +from neuroconv.utils import load_dict_from_file + +import lerner_lab_to_nwb.seiler_2024 as seiler_2024 +from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_dataset import SUBJECTS_TO_SKIP, get_opto_subject_id + + +def test_institution(): + metadata = load_dict_from_file(Path(seiler_2024.__file__).parent / "seiler_2024_metadata.yaml") + assert metadata["NWBFile"]["institution"] == "Northwestern University" + + +class TestSubject262478: + def test_nphr_run_is_converted(self): + subject_id = get_opto_subject_id(Path("Group 2/NpHr/2021-10-29_262_259.478")) + assert subject_id == "262.478" + assert subject_id not in SUBJECTS_TO_SKIP + + def test_scrambled_copy_is_skipped(self): + subject_id = get_opto_subject_id(Path("Group 2/Scrambled/2021-10-29_262_259 - Copy.478")) + assert subject_id in SUBJECTS_TO_SKIP From 3dc3f53fe876eea812c65a78f4d6392625c9dbfb Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Mon, 19 Oct 2026 14:24:09 -0700 Subject: [PATCH 2/3] Move the audit notebook out of the repo Co-Authored-By: Claude Opus 5.5 --- notebooks/subject_labels.ipynb | 479 --------------------------------- 1 file changed, 479 deletions(-) delete mode 100644 notebooks/subject_labels.ipynb diff --git a/notebooks/subject_labels.ipynb b/notebooks/subject_labels.ipynb deleted file mode 100644 index 3b632c8..0000000 --- a/notebooks/subject_labels.ipynb +++ /dev/null @@ -1,479 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3c282cee", - "metadata": {}, - "source": [ - "# Mouse 262.478 and the institution name\n", - "\n", - "Every raw file and `Subject:` field for this DMS Inhibitory Group 2 mouse reads `262` or `262.478`. Only the file name `2021-10-29_262_259.478`, which also has a copy in `Scrambled`, reads 262.259. The demographics sheet originally listed 262.478; in May 2024 the conversion's copy of the sheet was changed to 262.259 to match that one file name, which made 262.478 \"missing\" and dropped the mouse's other sessions. DANDI:000971 holds only the Scrambled copy of the 10/29 run, labeled NpHRScrambled.\n", - "\n", - "With the sheet row set back to 262.478, this notebook converts the mouse's sessions and compares the 10/29 run with the published file. It also shows the institution name, which was misspelled in every published file." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "32be112c", - "metadata": { - "execution": { - "iopub.execute_input": "2026-10-19T17:35:21.064513Z", - "iopub.status.busy": "2026-10-19T17:35:21.064303Z", - "iopub.status.idle": "2026-10-19T17:35:23.569079Z", - "shell.execute_reply": "2026-10-19T17:35:23.568623Z" - } - }, - "outputs": [], - "source": [ - "from pathlib import Path\n", - "import shutil\n", - "\n", - "import h5py\n", - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_dataset import (\n", - " SUBJECTS_TO_SKIP,\n", - " opto_to_nwb,\n", - " get_no_port_entry_duration_sessions,\n", - " get_session_key_from_kwargs,\n", - ")\n", - "from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_session import session_to_nwb\n", - "\n", - "data_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/_Raw_Data_for_future_reference\")\n", - "published_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/000971\")\n", - "output_dir_path = Path(\"/Volumes/T7/CatalystNeuro/Lerner/fix_audit/subject_labels\")\n", - "if output_dir_path.exists():\n", - " shutil.rmtree(output_dir_path)\n", - "output_dir_path.mkdir(parents=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "a6c63054", - "metadata": { - "execution": { - "iopub.execute_input": "2026-10-19T17:35:23.570947Z", - "iopub.status.busy": "2026-10-19T17:35:23.570732Z", - "iopub.status.idle": "2026-10-19T17:35:23.765237Z", - "shell.execute_reply": "2026-10-19T17:35:23.764929Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Mouse IDExperimentSexTreatment
149262.478DMS Inhibitory Group 2MaleInhibitory stimulation on rewarded nosepokes (...
\n", - "
" - ], - "text/plain": [ - " Mouse ID Experiment Sex \\\n", - "149 262.478 DMS Inhibitory Group 2 Male \n", - "\n", - " Treatment \n", - "149 Inhibitory stimulation on rewarded nosepokes (... " - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "demographics = pd.read_excel(data_dir_path / \"MouseDemographicsCorrected.xlsx\", sheet_name=\"Mouse Demographics\", dtype={\"Mouse ID\": str})\n", - "demographics[demographics[\"Mouse ID\"].str.startswith(\"262\")][[\"Mouse ID\", \"Experiment\", \"Sex\", \"Treatment\"]]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "f9eb7635", - "metadata": { - "execution": { - "iopub.execute_input": "2026-10-19T17:35:23.766882Z", - "iopub.status.busy": "2026-10-19T17:35:23.766730Z", - "iopub.status.idle": "2026-10-19T17:35:26.368998Z", - "shell.execute_reply": "2026-10-19T17:35:26.368705Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
sessions
subject_idtreatmentfileskipped
262.478NpHRDMS Inhibitory/Group 2/NpHr/262.478False18
262.259NpHRScrambledDMS Inhibitory/Group 2/Scrambled/2021-10-29_262_259 - Copy.478True1
262.478NpHRDMS Inhibitory/Group 2/NpHr/2021-10-25_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-26_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-27_262.478False1
DMS Inhibitory/Group 2/NpHr/2021-10-29_262_259.478False1
\n", - "
" - ], - "text/plain": [ - " sessions\n", - "subject_id treatment file skipped \n", - "262.478 NpHR DMS Inhibitory/Group 2/NpHr/262.478 False 18\n", - "262.259 NpHRScrambled DMS Inhibitory/Group 2/Scrambled/2021-10-29_262... True 1\n", - "262.478 NpHR DMS Inhibitory/Group 2/NpHr/2021-10-25_262.478 False 1\n", - " DMS Inhibitory/Group 2/NpHr/2021-10-26_262.478 False 1\n", - " DMS Inhibitory/Group 2/NpHr/2021-10-27_262.478 False 1\n", - " DMS Inhibitory/Group 2/NpHr/2021-10-29_262_259.478 False 1" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session_to_nwb_kwargs_per_session = [\n", - " session_to_nwb_kwargs\n", - " for session_to_nwb_kwargs in opto_to_nwb(\n", - " data_dir_path=data_dir_path, output_dir_path=output_dir_path, start_variable=\"Start Date\", verbose=False\n", - " )\n", - " if session_to_nwb_kwargs[\"subject_id\"].startswith(\"262\")\n", - "]\n", - "pd.DataFrame(\n", - " [\n", - " dict(\n", - " subject_id=session_to_nwb_kwargs[\"subject_id\"],\n", - " treatment=session_to_nwb_kwargs[\"optogenetic_treatment\"],\n", - " file=session_to_nwb_kwargs[\"behavior_file_path\"].relative_to(data_dir_path / \"Opto Experiments\").as_posix(),\n", - " skipped=session_to_nwb_kwargs[\"subject_id\"] in SUBJECTS_TO_SKIP,\n", - " )\n", - " for session_to_nwb_kwargs in session_to_nwb_kwargs_per_session\n", - " ]\n", - ").value_counts().to_frame(\"sessions\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "8b90a803", - "metadata": { - "execution": { - "iopub.execute_input": "2026-10-19T17:35:26.370472Z", - "iopub.status.busy": "2026-10-19T17:35:26.370354Z", - "iopub.status.idle": "2026-10-19T17:35:42.777986Z", - "shell.execute_reply": "2026-10-19T17:35:42.777699Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\r", - "Reading port entry durations: 0%| | 0/22 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
versionfilesubject_idsexstimulus_notesinstitution
0publishedsub-262-259_ses-Opto-DMS-Inhibitory-NpHRScramb...262.259MInhibitory stimulation on rewarded nosepokes (...Northwestern Unitersity
1fixedsub-262.478_ses-Opto-DMS-Inhibitory-NpHR-2021-...262.478MInhibitory stimulation on rewarded nosepokes (...Northwestern University
\n", - "" - ], - "text/plain": [ - " version file subject_id \\\n", - "0 published sub-262-259_ses-Opto-DMS-Inhibitory-NpHRScramb... 262.259 \n", - "1 fixed sub-262.478_ses-Opto-DMS-Inhibitory-NpHR-2021-... 262.478 \n", - "\n", - " sex stimulus_notes \\\n", - "0 M Inhibitory stimulation on rewarded nosepokes (... \n", - "1 M Inhibitory stimulation on rewarded nosepokes (... \n", - "\n", - " institution \n", - "0 Northwestern Unitersity \n", - "1 Northwestern University " - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def summarize(file_path: Path) -> dict:\n", - " with h5py.File(file_path, \"r\") as file:\n", - " return dict(\n", - " file=file_path.name,\n", - " subject_id=file[\"general/subject/subject_id\"][()].decode(),\n", - " sex=file[\"general/subject/sex\"][()].decode(),\n", - " stimulus_notes=file[\"general/stimulus\"][()].decode(),\n", - " institution=file[\"general/institution\"][()].decode(),\n", - " )\n", - "\n", - "\n", - "def read_behavior_datasets(file_path: Path) -> dict[str, np.ndarray]:\n", - " datasets = {}\n", - " with h5py.File(file_path, \"r\") as file:\n", - " for group in (\"processing/behavior\", \"stimulus\"):\n", - " if group in file:\n", - " file[group].visititems(\n", - " lambda name, item: datasets.__setitem__(f\"{group}/{name}\", item[()]) if isinstance(item, h5py.Dataset) else None\n", - " )\n", - " return datasets\n", - "\n", - "\n", - "(published_file_path,) = (published_dir_path / \"sub-262-259\").glob(\"*.nwb\")\n", - "(new_file_path,) = output_dir_path.glob(\"*2021-10-29T15-11-08*.nwb\")\n", - "pd.DataFrame([dict(version=\"published\", **summarize(published_file_path)), dict(version=\"fixed\", **summarize(new_file_path))])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "d022c2f1", - "metadata": { - "execution": { - "iopub.execute_input": "2026-10-19T17:35:42.789336Z", - "iopub.status.busy": "2026-10-19T17:35:42.789256Z", - "iopub.status.idle": "2026-10-19T17:35:42.793832Z", - "shell.execute_reply": "2026-10-19T17:35:42.793578Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "same datasets: True\n", - "same values: True\n" - ] - } - ], - "source": [ - "published_datasets = read_behavior_datasets(published_file_path)\n", - "new_datasets = read_behavior_datasets(new_file_path)\n", - "print(\"same datasets:\", set(published_datasets) == set(new_datasets))\n", - "print(\"same values:\", all(np.array_equal(published_datasets[name], new_datasets[name]) for name in new_datasets))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "lerner_lab_to_nwb_env", - "language": "python", - "name": "lerner_lab_to_nwb_env" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 98a1f99b88569e4baf1b108c5d294e475249a655 Mon Sep 17 00:00:00 2001 From: pauladkisson Date: Tue, 20 Oct 2026 10:11:32 -0700 Subject: [PATCH 3/3] Move the institution fix to its own PR Co-Authored-By: Claude Opus 5.5 --- .../seiler_2024/seiler_2024_metadata.yaml | 2 +- tests/test_subject_labels.py | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) 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 f39b6a1..0e964af 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 @@ -13,7 +13,7 @@ NWBFile: Amplifying this dopamine signal accelerated animals' transitions to compulsion, whereas inhibition delayed it. In contrast, amplifying DLS dopamine signaling had no effect on the emergence of compulsions. These results establish DMS dopamine signaling as a key controller of the development of compulsive reward seeking. - institution: Northwestern University + institution: Northwestern Unitersity lab: Lerner experimenter: - Seiler, Jillian L. diff --git a/tests/test_subject_labels.py b/tests/test_subject_labels.py index 6783d0b..c094685 100644 --- a/tests/test_subject_labels.py +++ b/tests/test_subject_labels.py @@ -1,16 +1,8 @@ from pathlib import Path -from neuroconv.utils import load_dict_from_file - -import lerner_lab_to_nwb.seiler_2024 as seiler_2024 from lerner_lab_to_nwb.seiler_2024.seiler_2024_convert_dataset import SUBJECTS_TO_SKIP, get_opto_subject_id -def test_institution(): - metadata = load_dict_from_file(Path(seiler_2024.__file__).parent / "seiler_2024_metadata.yaml") - assert metadata["NWBFile"]["institution"] == "Northwestern University" - - class TestSubject262478: def test_nphr_run_is_converted(self): subject_id = get_opto_subject_id(Path("Group 2/NpHr/2021-10-29_262_259.478"))