Skip to content

Commit eb62f84

Browse files
committed
loris bids importer package
1 parent 5ae29e1 commit eb62f84

27 files changed

Lines changed: 217 additions & 133 deletions

.github/labeler.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
- changed-files:
77
- any-glob-to-any-file: '**/*.py'
88

9+
"Package: BIDS importer":
10+
- changed-files:
11+
- any-glob-to-any-file: 'python/loris_bids_importer/**'
12+
913
"Package: BIDS reader":
1014
- changed-files:
1115
- any-glob-to-any-file: 'python/loris_bids_reader/**'

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies = [
2424
"scipy",
2525
"sqlalchemy>=2.0.0",
2626
"typing-extensions",
27+
"loris-bids-importer @ {root:uri}/python/loris_bids_importer",
2728
"loris-bids-reader @ {root:uri}/python/loris_bids_reader",
2829
"loris-dicom-importer @ {root:uri}/python/loris_dicom_importer",
2930
"loris-ephys-chunker @ {root:uri}/python/loris_ephys_chunker",
@@ -53,6 +54,7 @@ packages = [
5354
members = ["python/loris_*"]
5455

5556
[tool.uv.sources]
57+
loris_bids_importer = { workspace = true }
5658
loris_bids_reader = { workspace = true }
5759
loris_dicom_importer = { workspace = true }
5860
loris_ephys_chunker = { workspace = true }
@@ -83,21 +85,23 @@ include = [
8385
"python/tests",
8486
"python/lib/db",
8587
"python/lib/imaging_lib",
86-
"python/lib/import_bids_dataset",
8788
"python/lib/physio",
8889
"python/lib/config.py",
8990
"python/lib/config_file.py",
9091
"python/lib/env.py",
9192
"python/lib/get_session_info.py",
9293
"python/lib/logging.py",
9394
"python/lib/make_env.py",
94-
"python/scripts/import_bids_dataset.py",
9595
"python/loris_bids_reader",
96+
"python/loris_bids_importer",
9697
"python/loris_dicom_importer",
9798
"python/loris_ephys_chunker",
9899
"python/loris_utils",
99100
]
100101
exclude = [
102+
# Legacy EEG BIDS import code.
103+
"python/loris_bids_importer/src/loris_bids_importer/eeg",
104+
# Generated protocol buffer code.
101105
"python/loris_ephys_chunker/src/loris_ephys_chunker/protocol_buffers",
102106
]
103107
typeCheckingMode = "strict"

python/lib/dcm2bids_imaging_pipeline_lib/nifti_insertion_pipeline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import sys
77
from pathlib import Path
88

9+
from loris_bids_importer.file_type import get_check_bids_imaging_file_type_from_extension
10+
from loris_bids_importer.mri.sidecar import add_bids_mri_sidecar_file_parameters, get_bids_mri_sidecar_session_info
911
from loris_bids_reader.mri.sidecar import BidsMriSidecarJsonFile
1012
from loris_utils.crypto import compute_file_blake2b_hash, compute_file_md5_hash
1113

@@ -19,8 +21,6 @@
1921
from lib.imaging_lib.file_parameter import register_mri_file_parameter, register_mri_file_parameters
2022
from lib.imaging_lib.nifti import add_nifti_spatial_file_parameters
2123
from lib.imaging_lib.nifti_pic import create_nifti_preview_picture
22-
from lib.import_bids_dataset.file_type import get_check_bids_imaging_file_type_from_extension
23-
from lib.import_bids_dataset.mri_sidecar import add_bids_mri_sidecar_file_parameters, get_bids_mri_sidecar_session_info
2424
from lib.logging import log_error_exit, log_verbose
2525

2626

python/lib/imaging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def __init__(self, db, verbose, config_file=None):
7676
self.param_type_db_obj = ParameterType(db, verbose)
7777
self.param_file_db_obj = ParameterFile(db, verbose)
7878

79-
@deprecated('Use `lib.import_bids_dataset.file_type.get_check_bids_imaging_file_type_from_extension` instead.')
79+
@deprecated('Use `loris_bids_importer.file_type.get_check_bids_imaging_file_type_from_extension` instead.')
8080
def determine_file_type(self, file):
8181
"""
8282
Greps all file types defined in the ImagingFileTypes table and checks
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# LORIS BIDS importer
2+
3+
## Description
4+
5+
The LORIS BIDS importer is a pipeline that allows to ingest an external BIDS dataset into LORIS, populating both the database and the file-system.
6+
7+
The LORIS BIDS importer supports the MRI (NIfTI), EEG/iEEG (EDF/EEGLAB), and MEG (CTF) modalities.
8+
9+
## Installation
10+
11+
This package is installed by default with LORIS Python.
12+
13+
## Script
14+
15+
The LORIS BIDS importer can be ran with the following command:
16+
17+
```sh
18+
import-bids-dataset -d /path/to/bids/dataset`
19+
```
20+
21+
The directory passed as an argument should be a BIDS compliant dataset (see the [BIDS specification](https://bids-specification.readthedocs.io/en/stable/)).
22+
23+
## Parameters
24+
25+
### Subject and session validation
26+
27+
To be imported into LORIS, a BIDS dataset must adhere to the following rules:
28+
- The subject labels of the BIDS dataset should map to LORIS candidate CandIDs or PSCIDs.
29+
- The session labels of the BIDS dataset should map to LORIS visit labels.
30+
31+
If the candidates or sessions do not exist yet in LORIS, they can be created automatically from the BIDS dataset information using the following options:
32+
- `--create-candidate`: Create new LORIS candidates, in which case the subject label must be a PSCID (and not a CandID).
33+
- `--create-session`: Create new LORIS sessions.
34+
35+
Note that these options may require additional information such as the candidate and session projects, sites, and cohorts from the `participants.tsv`, `sessions.tsv`, or `scans.tsv` BIDS files.
36+
37+
### File copy
38+
39+
By default, the files imported from the source BIDS dataset are copied in a new BIDS dataset in the LORIS data directory. The `--no-copy` option allows to re-use the original BIDS files without copy if the source BIDS dataset is already located in the LORIS data directory.
40+
41+
### Other parameters
42+
43+
To see all the CLI parameters of the LORIS BIDS importer, use `import-bids-dataset --help`.
44+
45+
## Supported files
46+
47+
The LORIS BIDS importer can import the following BIDS files:
48+
- Static dataset files: `dataset_description.json`, `README`.
49+
- Dataset structure files: `participants.tsv`, `scans.tsv`.
50+
- MRI acquisition files: NIfTI (`.nii`, `.nii.gz`) and their JSON sidecars.
51+
- EEG/iEEG/MEG acquisition files: EDF (`.edf`), EEGLAB (`.set`), CTF (`.ds` directories), and their JSON sidecars.
52+
- EEG/iEEG/MEG metadata files: `coordsystem.json`, `electrodes.tsv`, `channels.tsv`, `events.json`, `events.tsv`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[project]
2+
name = "loris-bids-importer"
3+
version = "27.0.0"
4+
description = "The LORIS BIDS importer"
5+
readme = "README.md"
6+
license = "GPL-3.0-or-later"
7+
requires-python = ">= 3.11"
8+
dependencies = [
9+
"loris-bids-reader",
10+
"loris-utils",
11+
]
12+
13+
[project.scripts]
14+
import-bids-dataset = "loris_bids_importer.scripts.import_bids_dataset:main"
15+
16+
[build-system]
17+
requires = ["hatchling"]
18+
build-backend = "hatchling.build"
19+
20+
[tool.hatch.metadata]
21+
allow-direct-references = true
22+
23+
[tool.hatch.build.targets.wheel]
24+
packages = ["src/loris_bids_importer"]
25+
26+
[tool.ruff]
27+
extend = "../../pyproject.toml"
28+
src = ["src"]

python/lib/import_bids_dataset/acquisitions.py renamed to python/loris_bids_importer/src/loris_bids_importer/acquisitions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from collections.abc import Callable
22
from typing import TypeVar
33

4-
from loris_bids_reader.info import BidsAcquisitionInfo
5-
64
from lib.env import Env
7-
from lib.import_bids_dataset.env import BidsImportEnv
85
from lib.logging import log, log_error
6+
from loris_bids_reader.info import BidsAcquisitionInfo
7+
8+
from loris_bids_importer.env import BidsImportEnv
99

1010
T = TypeVar('T')
1111

python/lib/import_bids_dataset/archive.py renamed to python/loris_bids_importer/src/loris_bids_importer/archive.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
from pathlib import Path
22

3-
from loris_utils.archive import create_archive_with_files
4-
from loris_utils.crypto import compute_file_blake2b_hash
5-
from loris_utils.path import remove_path_extension
6-
73
from lib.config import get_data_dir_path_config, get_ephys_archive_dir_path_config
84
from lib.db.models.physio_event_archive import DbPhysioEventArchive
95
from lib.db.models.physio_file import DbPhysioFile
106
from lib.db.models.physio_file_archive import DbPhysioFileArchive
117
from lib.env import Env
8+
from loris_utils.archive import create_archive_with_files
9+
from loris_utils.crypto import compute_file_blake2b_hash
10+
from loris_utils.path import remove_path_extension
1211

1312

1413
def import_physio_file_archive(env: Env, physio_file: DbPhysioFile, file_paths: list[Path]):
File renamed without changes.

python/lib/import_bids_dataset/channels.py renamed to python/loris_bids_importer/src/loris_bids_importer/channels.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
from pathlib import Path
22

3-
from loris_bids_reader.eeg.channels import BidsEegChannelsTsvFile, BidsEegChannelTsvRow
4-
from loris_bids_reader.info import BidsAcquisitionInfo
5-
from loris_utils.crypto import compute_file_blake2b_hash
6-
from loris_utils.error import group_errors, group_errors_tuple
7-
83
from lib.db.models.physio_channel_type import DbPhysioChannelType
94
from lib.db.models.physio_file import DbPhysioFile
105
from lib.db.models.physio_status_type import DbPhysioStatusType
116
from lib.db.models.session import DbSession
127
from lib.db.queries.physio_channel import try_get_channel_type_with_name, try_get_status_type_with_name
138
from lib.env import Env
14-
from lib.import_bids_dataset.copy_files import get_loris_bids_file_path
15-
from lib.import_bids_dataset.env import BidsImportEnv
169
from lib.physio.channels import insert_physio_channel
1710
from lib.physio.parameters import insert_physio_file_parameter
11+
from loris_bids_reader.eeg.channels import BidsEegChannelsTsvFile, BidsEegChannelTsvRow
12+
from loris_bids_reader.info import BidsAcquisitionInfo
13+
from loris_utils.crypto import compute_file_blake2b_hash
14+
from loris_utils.error import group_errors, group_errors_tuple
15+
16+
from loris_bids_importer.copy_files import get_loris_bids_file_path
17+
from loris_bids_importer.env import BidsImportEnv
1818

1919

2020
def insert_bids_channels_file(

0 commit comments

Comments
 (0)