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 ophys pipeline (Bruker) #4

Merged
merged 20 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
da6bbba
add skeleton for conversion of bruker imaging
weiglszonja Aug 8, 2023
650dc38
remove empty behavior interface
weiglszonja Aug 9, 2023
73682ce
Update src/pinto_lab_to_nwb/into_the_void/into_the_void_convert_sessi…
weiglszonja Aug 10, 2023
a2050ff
small update
weiglszonja Aug 10, 2023
8c321e0
Merge branch 'main' into add_two_photon_pipeline
weiglszonja Sep 21, 2023
569ae5b
Merge branch 'main' into add_two_photon_pipeline
weiglszonja Nov 18, 2023
bffe491
update converter
weiglszonja Nov 20, 2023
e236845
add notes
weiglszonja Nov 20, 2023
d14e34e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2023
92937cd
extend notes
weiglszonja Nov 20, 2023
e86f2f2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2023
9bd21b8
Merge branch 'main' into add_two_photon_pipeline
CodyCBakerPhD Nov 20, 2023
86e9b3a
update converter after suite2p datainterface has plane_segmentation_n…
weiglszonja Nov 20, 2023
a73be3e
Merge remote-tracking branch 'origin/add_two_photon_pipeline' into ad…
weiglszonja Nov 20, 2023
d3b0270
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2023
74f037c
Merge branch 'main' into add_two_photon_pipeline
weiglszonja Nov 20, 2023
dca101d
fix metadata links
weiglszonja Nov 21, 2023
25e3fbb
update notes
weiglszonja Nov 21, 2023
d64fbdb
Merge remote-tracking branch 'origin/add_two_photon_pipeline' into ad…
weiglszonja Nov 21, 2023
83eefe1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 21, 2023
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
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pip install -r src/pinto_lab_to_nwb/into_the_void/into_the_void_requirements.txt

You can run a specific conversion with the following command:
```
python src/pinto_lab_to_nwb/into_the_void/into_the_void_conversion_script.py
python src/pinto_lab_to_nwb/into_the_void/into_the_void_convert_session.py
```

## Repository structure
Expand All @@ -69,26 +69,22 @@ Each conversion is organized in a directory of its own in the `src` directory:
├── setup.py
└── src
├── pinto_lab_to_nwb
│ ├── conversion_directory_1
│ └── into_the_void
│ ├── into_the_voidbehaviorinterface.py
│ ├── general_metadata.yaml
│ ├── into_the_void_convert_session.py
│ ├── into_the_void_metadata.yml
│ ├── into_the_voidnwbconverter.py
│ ├── into_the_void_requirements.txt
│ ├── into_the_void_notes.md

│ └── __init__.py
│ ├── conversion_directory_b

└── __init__.py

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

* `into_the_void_convert_sesion.py`: this script defines the function to convert one full session of the conversion.
* `into_the_void_requirements.txt`: dependencies specific to this conversion.
* `into_the_void_metadata.yml`: metadata in yaml format for this specific conversion.
* `into_the_voidbehaviorinterface.py`: the behavior interface. Usually ad-hoc for each conversion.
* `general_metadata.yml`: general metadata in yaml format (e.g. session description, experimenter, subject metadata).
* `into_the_voidnwbconverter.py`: the place where the `NWBConverter` class is defined.
* `into_the_void_notes.md`: notes and comments concerning this specific conversion.

Expand Down
Empty file.
1 change: 0 additions & 1 deletion src/pinto_lab_to_nwb/into_the_void/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from .into_the_voidbehaviorinterface import IntoTheVoidBehaviorInterface
from .into_the_voidnwbconverter import IntoTheVoidNWBConverter
10 changes: 10 additions & 0 deletions src/pinto_lab_to_nwb/into_the_void/general_metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NWBFile:
session_description:
A rich text description of the experiment. Can also just be the abstract of the publication.
institution: Northwestern University
lab: Pinto
experimenter:
- Canton, Neto
Subject:
species: Mus musculus
sex: U
100 changes: 62 additions & 38 deletions src/pinto_lab_to_nwb/into_the_void/into_the_void_convert_session.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,92 @@
"""Primary script to run to convert an entire session for of data using the NWBConverter."""
import re
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 typing import Optional
from dateutil import tz
from neuroconv.utils import (
load_dict_from_file,
dict_deep_update,
FolderPathType,
FilePathType,
)

from pinto_lab_to_nwb.into_the_void import IntoTheVoidNWBConverter


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)
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"
def session_to_nwb(
nwbfile_path: FilePathType,
two_photon_imaging_folder_path: FolderPathType,
segmentation_folder_path: Optional[FolderPathType] = None,
stub_test: bool = False,
):
"""
Converts a single session to NWB.

Parameters
----------
nwbfile_path : FilePathType
The file path to the NWB file that will be created.
two_photon_imaging_folder_path: FolderPathType
The folder path that contains the Bruker TIF imaging output (.ome.tif files).
segmentation_folder_path: FolderPathType
The folder that contains the Suite2P segmentation output.
stub_test: bool, optional
For testing purposes, when stub_test=True only writes a subset of imaging and segmentation data.
"""

source_data = dict()
conversion_options = dict()

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

# Add LFP
source_data.update(dict(LFP=dict()))
conversion_options.update(dict(LFP=dict()))
# Add Imaging
imaging_source_data = dict(folder_path=str(two_photon_imaging_folder_path))
source_data.update(dict(Imaging=imaging_source_data))
conversion_options.update(dict(Imaging=dict(stub_test=stub_test)))

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

# Add Behavior
source_data.update(dict(Behavior=dict()))
conversion_options.update(dict(Behavior=dict()))
# Add Segmentation (optional)
if segmentation_folder_path:
segmentation_source_data = dict(folder_path=str(segmentation_folder_path))
source_data.update(dict(Segmentation=segmentation_source_data))
conversion_options.update(dict(Segmentation=dict(stub_test=False)))

converter = IntoTheVoidNWBConverter(source_data=source_data)

# Add datetime to conversion
metadata = converter.get_metadata()
datetime.datetime(year=2020, month=1, day=1, tzinfo=ZoneInfo("US/Eastern"))
date = datetime.datetime.today() # TO-DO: Get this from author
metadata["NWBFile"]["session_start_time"] = date
# For data provenance we can add the time zone information to the conversion if missing
session_start_time = metadata["NWBFile"]["session_start_time"]
tzinfo = tz.gettz("US/Pacific")
metadata["NWBFile"].update(session_start_time=session_start_time.replace(tzinfo=tzinfo))

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

# Update metadata with subject_id and session_id from folder_path
# NCCR51_2023_04_07_no_task_dual_color_jrgeco_t_series-001
file_naming_pattern = r"^(?P<subject_id>[^_]+)_(?:\d{4}_\d{2}_\d{2}_)(?P<session_id>.+)"
match = re.match(file_naming_pattern, str(two_photon_imaging_folder_path))
weiglszonja marked this conversation as resolved.
Show resolved Hide resolved
if match:
groups_dict = match.groupdict()
metadata["NWBFile"].update(session_id=groups_dict["session_id"].replace("_", "-"))
metadata["Subject"].update(subject_id=groups_dict["subject_id"])

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


if __name__ == "__main__":
# Parameters for conversion
data_dir_path = Path("/Directory/With/Raw/Formats/")
output_dir_path = Path("~/conversion_nwb/")
stub_test = False
imaging_folder_path = Path("/Volumes/t7-ssd/Pinto/NCCR62_2023_07_06_IntoTheVoid_t_series_Dual_color-000")
segmentation_folder_path = imaging_folder_path / "suite2p"
nwbfile_path = Path("/Volumes/t7-ssd/Pinto/nwbfiles/imaging_stub2.nwb")
stub_test = True

session_to_nwb(
data_dir_path=data_dir_path,
output_dir_path=output_dir_path,
nwbfile_path=nwbfile_path,
two_photon_imaging_folder_path=imaging_folder_path,
segmentation_folder_path=segmentation_folder_path,
stub_test=stub_test,
)
12 changes: 0 additions & 12 deletions src/pinto_lab_to_nwb/into_the_void/into_the_void_metadata.yaml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
neuroconv[suite2p, brukertiff]

This file was deleted.

15 changes: 4 additions & 11 deletions src/pinto_lab_to_nwb/into_the_void/into_the_voidnwbconverter.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
"""Primary NWBConverter class for this dataset."""
from neuroconv import NWBConverter
from neuroconv.datainterfaces import (
SpikeGLXRecordingInterface,
SpikeGLXLFPInterface,
PhySortingInterface,
)

from pinto_lab_to_nwb.into_the_void import IntoTheVoidBehaviorInterface
from neuroconv.datainterfaces import Suite2pSegmentationInterface
from neuroconv.converters import BrukerTiffSinglePlaneConverter


class IntoTheVoidNWBConverter(NWBConverter):
"""Primary conversion class for my extracellular electrophysiology dataset."""

data_interface_classes = dict(
Recording=SpikeGLXRecordingInterface,
LFP=SpikeGLXLFPInterface,
Sorting=PhySortingInterface,
Behavior=IntoTheVoidBehaviorInterface,
Imaging=BrukerTiffSinglePlaneConverter,
Segmentation=Suite2pSegmentationInterface,
)