Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fiber photometry interface #2

Merged
merged 7 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/test-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ jobs:
run: pip install -e .
- name: Test module load
run: python -c "import hnasko_lab_to_nwb"

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,4 @@ dmypy.json
.DS_Store

# NWB files
**.nwb
**.nwb
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ repos:
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
additional_dependencies:
- tomli

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
- id: ruff
args: [ --fix ]
args: [ --fix ]
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pip install hnasko-lab-to-nwb

We recommend that you install the package inside a [virtual environment](https://docs.python.org/3/tutorial/venv.
html). A simple way of doing this is to use a [conda environment](https://docs.conda.
io/projects/conda/en/latest/user-guide/concepts/environments.html) from the `conda` package manager ([installation
instructions](https://docs.conda.io/en/latest/miniconda.html)). Detailed instructions on how to use conda
io/projects/conda/en/latest/user-guide/concepts/environments.html) from the `conda` package manager ([installation
instructions](https://docs.conda.io/en/latest/miniconda.html)). Detailed instructions on how to use conda
environments can be found in their [documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html).

### Running a specific conversion
Expand All @@ -30,10 +30,10 @@ python convert_session.py
```

## Installation from GitHub
Another option is to install the package directly from GitHub. This option has the advantage that the source code
can be modified if you need to amend some of the code we originally provided to adapt to future experimental
differences. To install the conversion from GitHub you will need to use `git` ([installation instructions] (https://github.com/git-guides/install-git)).
We also recommend the installation of `conda` ([installation instructions](https://docs.conda.io/en/latest/miniconda.html)) as it contains all the required
Another option is to install the package directly from GitHub. This option has the advantage that the source code
can be modified if you need to amend some of the code we originally provided to adapt to future experimental
differences. To install the conversion from GitHub you will need to use `git` ([installation instructions] (https://github.com/git-guides/install-git)).
We also recommend the installation of `conda` ([installation instructions](https://docs.conda.io/en/latest/miniconda.html)) as it contains all the required
machinery in a single and simple install.

From a terminal (note that conda should install one in your system) you can do the following:
Expand All @@ -47,7 +47,7 @@ conda activate hnasko-lab-to-nwb-env

This creates a [conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html) which isolates the conversion code from your system libraries. We recommend that you run all your conversion related tasks and analysis from the created environment in order to minimize issues related to package dependencies.

Alternatively, if you want to avoid conda altogether (for example if you use another virtual environment tool) you
Alternatively, if you want to avoid conda altogether (for example if you use another virtual environment tool) you
can install the repository with the following commands using only pip:

```
Expand Down Expand Up @@ -94,11 +94,11 @@ Each conversion is organized in a directory of its own in the `src` directory:

└── __init__.py

For example, for the conversion `embargo_2025` you can find a directory located in `src/hnasko-lab-to-nwb/embargo_2025`.
For example, for the conversion `embargo_2025` you can find a directory located in `src/hnasko-lab-to-nwb/embargo_2025`.
Inside each conversion directory you can find the following files:


* `convert_sesion.py`: this script defines the function to convert one full session of the conversion.
* `convert_sesion.py`: this script defines the function to convert one full session of the conversion.
* `metadata.yml`: metadata in yaml format for this specific conversion.
* `behaviorinterface.py`: the behavior interface. Usually ad-hoc for each conversion.
* `nwbconverter.py`: the place where the `NWBConverter` class is defined.
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,3 @@ fixable = ["ALL"]
[tool.ruff.lint.isort]
relative-imports-order = "closest-to-furthest"
known-first-party = ["neuroconv"]

2 changes: 0 additions & 2 deletions src/hnasko_lab_to_nwb/embargo_2025/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
from .behaviorinterface import Embargo2025BehaviorInterface
from .nwbconverter import Embargo2025NWBConverter
25 changes: 0 additions & 25 deletions src/hnasko_lab_to_nwb/embargo_2025/behaviorinterface.py

This file was deleted.

19 changes: 10 additions & 9 deletions src/hnasko_lab_to_nwb/embargo_2025/convert_all_sessions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Primary script to run to convert all sessions in a dataset using session_to_nwb."""
from pathlib import Path
from typing import Union
import traceback
from concurrent.futures import ProcessPoolExecutor, as_completed
from pathlib import Path
from pprint import pformat
import traceback
from typing import Union

from tqdm import tqdm

from .embargo_2025_convert_session import session_to_nwb
Expand Down Expand Up @@ -39,7 +40,7 @@ def dataset_to_nwb(
for session_to_nwb_kwargs in session_to_nwb_kwargs_per_session:
session_to_nwb_kwargs["output_dir_path"] = output_dir_path
session_to_nwb_kwargs["verbose"] = verbose
exception_file_path = data_dir_path / f"ERROR_<nwbfile_name>.txt" # Add error file path here
exception_file_path = data_dir_path / f"ERROR_<nwbfile_name>.txt" # Add error file path here
futures.append(
executor.submit(
safe_session_to_nwb,
Expand Down Expand Up @@ -86,11 +87,11 @@ def get_session_to_nwb_kwargs_per_session(
list[dict[str, Any]]
A list of dictionaries containing the kwargs for session_to_nwb for each session.
"""
#####
# # Implement this function to return the kwargs for session_to_nwb for each session
# This can be a specific list with hard-coded sessions, a path expansion or any conversion specific logic that you might need
#####
raise NotImplementedError
#####
# # Implement this function to return the kwargs for session_to_nwb for each session
# This can be a specific list with hard-coded sessions, a path expansion or any conversion specific logic that you might need
#####
raise NotImplementedError


if __name__ == "__main__":
Expand Down
111 changes: 71 additions & 40 deletions src/hnasko_lab_to_nwb/embargo_2025/convert_session.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,101 @@
"""Primary script to run to convert an entire session for of data using the NWBConverter."""

from pathlib import Path
from typing import Union
import datetime
from zoneinfo import ZoneInfo

from neuroconv.utils import load_dict_from_file, dict_deep_update

from .embargo_2025 import Embargo2025NWBConverter
from nwbconverter import Embargo2025NWBConverter

from neuroconv.utils import dict_deep_update, load_dict_from_file

def session_to_nwb(data_dir_path: Union[str, Path], output_dir_path: Union[str, Path], stub_test: bool = False):

data_dir_path = Path(data_dir_path)
def session_to_nwb(
output_dir_path: Union[str, Path],
subject_id: str,
session_id: str,
tdt_folder_path: Union[str, Path],
protocol_type: str,
stub_test: bool = False,
):
output_dir_path = Path(output_dir_path)
if stub_test:
output_dir_path = output_dir_path / "nwb_stub"
output_dir_path.mkdir(parents=True, exist_ok=True)

session_id = "subject_identifier_usually"
nwbfile_path = output_dir_path / f"{session_id}.nwb"

nwbfile_path = output_dir_path / f"sub-{subject_id}_ses-{session_id}.nwb"

valid_protocols = {"Varying durations", "Varying frequencies", "Shocks"}
if protocol_type not in valid_protocols:
raise ValueError(f"Invalid protocol_type: {protocol_type}. Must be one of {valid_protocols}.")
if protocol_type == "Varying durations":
session_description = (
"The subject is placed in a plastic tub and is recorded for 3.5 minutes. "
"The subject receives a 40 Hz stimulation at various durations (i.e. 250ms, 1s and 4s) "
"5 times for each duration) with an inter-stimulus interval (ISI) of 10s. "
)
elif protocol_type == "Varying frequencies":
session_description = (
"The subject is placed in a plastic tub and undergoes 3 recording sessions corresponding "
"to a fixed duration of stimulation (i.e., 250ms, 1s, and 4s). Each session lasted 8 minutes. "
"The subject receives optogenetic stimulation at varying frequencies "
"(5 Hz, 10 Hz , 20 Hz and 40 Hz) 5 times for each duration with an ISI of 10s. "
)
elif protocol_type == "Shocks":
session_description = (
"The subject is placed in a shock chamber and recorded for 6 minutes. "
"Uncued shocks (0.3 mA) at various durations (250ms, 1s and 4s, 5 times for each duration) "
"are delivered in a randomized order and ISI."
)
source_data = dict()
conversion_options = dict()

# Add Recording
source_data.update(dict(Recording=dict()))
conversion_options.update(dict(Recording=dict(stub_test=stub_test)))

# Add Sorting
source_data.update(dict(Sorting=dict()))
conversion_options.update(dict(Sorting=dict()))
# Add FiberPhotometry

# Add Behavior
source_data.update(dict(Behavior=dict()))
conversion_options.update(dict(Behavior=dict()))
source_data.update(dict(FiberPhotometry=dict(folder_path=tdt_folder_path)))
conversion_options.update(dict(FiberPhotometry=dict()))

converter = Embargo2025NWBConverter(source_data=source_data)

# Add datetime to conversion
metadata = converter.get_metadata()
date = datetime.datetime(year=2020, month=1, day=1, tzinfo=ZoneInfo("US/Eastern"))
metadata["NWBFile"]["session_start_time"] = date

# Update default metadata with the editable in the corresponding yaml file
editable_metadata_path = Path(__file__).parent / "embargo_2025_metadata.yaml"
metadata = converter.get_metadata()
editable_metadata_path = Path(__file__).parent / "metadata.yaml"
editable_metadata = load_dict_from_file(editable_metadata_path)
metadata = dict_deep_update(metadata, editable_metadata)

metadata["Subject"]["subject_id"] = "a_subject_id" # Modify here or in the yaml file
metadata["Subject"]["subject_id"] = subject_id
metadata["NWBFile"]["session_id"] = session_id
metadata["NWBFile"]["session_description"] = session_description

# Run conversion
converter.run_conversion(metadata=metadata, nwbfile_path=nwbfile_path, conversion_options=conversion_options)
converter.run_conversion(
metadata=metadata, nwbfile_path=nwbfile_path, conversion_options=conversion_options, overwrite=True
)


if __name__ == "__main__":

# Parameters for conversion
data_dir_path = Path("/Directory/With/Raw/Formats/")
output_dir_path = Path("~/conversion_nwb/")
stub_test = False

<<<<<<< HEAD:hnasko-lab-to-nwb/src/hnasko_lab_to_nwb/embargo_2025/convert_session.py
session_to_nwb(data_dir_path=data_dir_path, output_dir_path=output_dir_path, stub_test=stub_test)
=======
session_to_nwb(data_dir_path=data_dir_path,
output_dir_path=output_dir_path,
stub_test=stub_test,
)
>>>>>>> main:hnasko-lab-to-nwb/src/hnasko_lab_to_nwb/embargo_2025/embargo_2025_convert_session.py
data_dir_path = Path("D:/Hnasko-CN-data-share/SN pan GABA recordings/PPN/")
output_dir_path = Path("D:/hnasko_lab_conversion_nwb")
from neuroconv.tools.path_expansion import LocalPathExpander

data_dir_path = "D:/Hnasko-CN-data-share/SN pan GABA recordings/PPN/"
# Specify source data
source_data_spec = {
"FiberPhotometry": {
"base_directory": data_dir_path + "Fiber photometry_TDT",
"folder_path": "{protocol_type}/{subject_id}-{session_id}",
}
}
# Instantiate LocalPathExpander
path_expander = LocalPathExpander()
# Expand paths and extract metadata
metadata_list = path_expander.expand_paths(source_data_spec)
for metadata in metadata_list:
session_to_nwb(
output_dir_path=output_dir_path,
subject_id=metadata["metadata"]["Subject"]["subject_id"],
session_id=metadata["metadata"]["NWBFile"]["session_id"],
tdt_folder_path=metadata["source_data"]["FiberPhotometry"]["folder_path"],
protocol_type=metadata["metadata"]["extras"]["protocol_type"],
stub_test=True,
)
Loading