Skip to content

Commit 4acc9b7

Browse files
committed
change nifti class to bids mri acquisiton
1 parent 8065764 commit 4acc9b7

File tree

5 files changed

+105
-121
lines changed

5 files changed

+105
-121
lines changed

python/lib/imaging_lib/bids/dataset.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
if TYPE_CHECKING:
1616
from lib.imaging_lib.bids.eeg.dataset import BIDSEEGDataType
17-
from lib.imaging_lib.bids.mri.dataset import BIDSMRIDataType, BIDSNifti
17+
from lib.imaging_lib.bids.mri.dataset import BIDSMRIAcquisition, BIDSMRIDataType
1818

1919

2020
PYBIDS_IGNORE = ['code', 'sourcedata', 'log', '.git']
@@ -41,7 +41,7 @@ def data_types(self) -> Iterator['BIDSDataType']:
4141
yield from session.data_types
4242

4343
@property
44-
def niftis(self) -> Iterator['BIDSNifti']:
44+
def niftis(self) -> Iterator['BIDSMRIAcquisition']:
4545
from lib.imaging_lib.bids.mri.dataset import BIDSMRIDataType
4646
for data_type in self.data_types:
4747
if isinstance(data_type, BIDSMRIDataType):
@@ -164,7 +164,7 @@ def data_types(self) -> Iterator['BIDSDataType']:
164164
yield from session.data_types
165165

166166
@property
167-
def niftis(self) -> Iterator['BIDSNifti']:
167+
def niftis(self) -> Iterator['BIDSMRIAcquisition']:
168168
from lib.imaging_lib.bids.mri.dataset import BIDSMRIDataType
169169
for data_type in self.data_types:
170170
if isinstance(data_type, BIDSMRIDataType):
@@ -223,7 +223,7 @@ def root_dataset(self) -> BIDSDataset:
223223
return self.subject.root_dataset
224224

225225
@property
226-
def niftis(self) -> Iterator['BIDSNifti']:
226+
def niftis(self) -> Iterator['BIDSMRIAcquisition']:
227227
for data_type in self.mri_data_types:
228228
yield from data_type.niftis
229229

python/lib/imaging_lib/bids/mri/dataset.py

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,53 @@
33
from pathlib import Path
44

55
from lib.imaging_lib.bids.dataset import BIDSDataset, BIDSDataType, BIDSSession, BIDSSubject
6-
from lib.imaging_lib.nifti import find_dir_nifti_files
7-
from lib.util.fs import replace_file_extension
6+
from lib.util.fs import remove_path_extension, replace_path_extension
87

98

109
class BIDSMRIDataType(BIDSDataType):
1110
@cached_property
12-
def niftis(self) -> list['BIDSNifti']:
11+
def niftis(self) -> list['BIDSMRIAcquisition']:
1312
"""
1413
The NIfTI files found in this MRI data type directory.
1514
"""
1615

17-
niftis: list[BIDSNifti] = []
16+
acquisitions: list[BIDSMRIAcquisition] = []
1817

19-
for nifti_path in find_dir_nifti_files(self.path):
20-
niftis.append(BIDSNifti(self, nifti_path.name))
18+
for file_path in self.path.iterdir():
19+
if file_path.name.endswith(('.nii', '.nii.gz')):
20+
acquisitions.append(BIDSMRIAcquisition(self, file_path))
2121

22-
return niftis
22+
return acquisitions
2323

2424

25-
class BIDSNifti:
25+
class BIDSMRIAcquisition:
2626
data_type: BIDSDataType
2727
path: Path
28+
nifti_path: Path
29+
sidecar_path: Path | None
30+
bval_path: Path | None
31+
bvec_path: Path | None
2832
suffix: str | None
2933

30-
def __init__(self, data_type: BIDSDataType, name: str):
31-
self.data_type = data_type
32-
self.path = data_type.path / name
34+
def __init__(self, data_type: BIDSDataType, nifti_path: Path):
35+
self.data_type = data_type
36+
self.path = remove_path_extension(nifti_path)
37+
self.nifti_path = data_type.path / nifti_path
3338

34-
suffix_match = re.search(r'_([a-zA-Z0-9]+)\.nii(\.gz)?$', self.name)
35-
if suffix_match is not None:
36-
self.suffix = suffix_match.group(1)
37-
else:
38-
self.suffix = None
39+
sidecar_path = replace_path_extension(self.path, 'json')
40+
self.sidecar_path = sidecar_path if sidecar_path.exists() else None
41+
42+
bval_path = replace_path_extension(self.path, 'bval')
43+
self.bval_path = bval_path if bval_path.exists() else None
44+
45+
bvec_path = replace_path_extension(self.path, 'bvec')
46+
self.bvec_path = bvec_path if bvec_path.exists() else None
47+
48+
suffix_match = re.search(r'_([a-zA-Z0-9]+)$', self.name)
49+
self.suffix = suffix_match.group(1) if suffix_match is not None else None
3950

4051
@property
41-
def name(self) -> str:
52+
def name(self):
4253
return self.path.name
4354

4455
@property
@@ -52,39 +63,3 @@ def subject(self) -> BIDSSubject:
5263
@property
5364
def session(self) -> BIDSSession:
5465
return self.data_type.session
55-
56-
def get_json_path(self) -> Path | None:
57-
"""
58-
Get the JSON sidecar file path of this NIfTI file if it exists.
59-
"""
60-
61-
json_name = replace_file_extension(self.name, 'json')
62-
json_path = self.data_type.path / json_name
63-
if not json_path.exists():
64-
return None
65-
66-
return json_path
67-
68-
def get_bval_path(self) -> Path | None:
69-
"""
70-
Get the BVAL file path of this NIfTI file if it exists.
71-
"""
72-
73-
bval_name = replace_file_extension(self.name, 'bval')
74-
bval_path = self.data_type.path / bval_name
75-
if not bval_path.exists():
76-
return None
77-
78-
return bval_path
79-
80-
def get_bvec_path(self) -> Path | None:
81-
"""
82-
Get the BVEC file path of this NIfTI file if it exists.
83-
"""
84-
85-
bvec_name = replace_file_extension(self.name, 'bvec')
86-
bvec_path = self.data_type.path / bvec_name
87-
if not bvec_path.exists():
88-
return None
89-
90-
return bvec_path

python/lib/imaging_lib/nifti.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from collections.abc import Iterator
21
from pathlib import Path
32
from typing import Any, cast
43

@@ -32,13 +31,3 @@ def add_nifti_file_parameters(nifti_path: Path, nifti_file_hash: str, file_param
3231

3332
# Add the file BLAKE2b hash.
3433
file_parameters['file_blake2b_hash'] = nifti_file_hash
35-
36-
37-
def find_dir_nifti_files(dir_path: Path) -> Iterator[Path]:
38-
"""
39-
Iterate over the Path objects of the NIfTI files found in a directory.
40-
"""
41-
42-
for item_path in dir_path.iterdir():
43-
if item_path.name.endswith(('.nii', '.nii.gz')):
44-
yield item_path

python/lib/import_bids_dataset/mri.py

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from lib.db.queries.mri_scan_type import try_get_mri_scan_type_with_name
99
from lib.env import Env
1010
from lib.imaging_lib.bids.json import add_bids_json_file_parameters
11-
from lib.imaging_lib.bids.mri.dataset import BIDSNifti
11+
from lib.imaging_lib.bids.mri.dataset import BIDSMRIAcquisition
1212
from lib.imaging_lib.bids.tsv_scans import add_scan_tsv_file_parameters
1313
from lib.imaging_lib.bids.util import determine_bids_file_type
1414
from lib.imaging_lib.file import register_imaging_file
@@ -19,7 +19,7 @@
1919
from lib.import_bids_dataset.env import BIDSImportEnv
2020
from lib.logging import log, log_warning
2121
from lib.util.crypto import compute_file_blake2b_hash
22-
from lib.util.fs import get_file_extension
22+
from lib.util.fs import get_path_extension
2323

2424
KNOWN_SUFFIXES_PER_MRI_DATA_TYPE = {
2525
'anat': [
@@ -38,24 +38,27 @@
3838
}
3939

4040

41-
def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, nifti: BIDSNifti):
41+
def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, acquisition: BIDSMRIAcquisition):
4242
"""
4343
Import a BIDS NIfTI file and its associated files in LORIS.
4444
"""
4545

4646
log(
4747
env,
4848
(
49-
f"Importing MRI file '{nifti.name}'... ({import_env.processed_files_count + 1}"
49+
f"Importing MRI acquisition '{acquisition.name}'... ({import_env.processed_files_count + 1}"
5050
f" / {import_env.total_files_count})"
5151
),
5252
)
5353

5454
# Get the relevant `scans.tsv` row if there is one.
5555

56-
tsv_scan = nifti.session.get_tsv_scan(nifti.name)
56+
tsv_scan = acquisition.session.get_tsv_scan(acquisition.nifti_path.name)
5757
if tsv_scan is None:
58-
log_warning(env, f"No scans.tsv row found for file '{nifti.name}', scans.tsv data will be ignored.")
58+
log_warning(
59+
env,
60+
f"No scans.tsv row found for acquisition '{acquisition.name}', scans.tsv data will be ignored.",
61+
)
5962

6063
# Get the path at which to copy the file.
6164

@@ -64,10 +67,10 @@ def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, n
6467
cast(Path, import_env.loris_bids_path)
6568
/ f'sub-{session.candidate.psc_id}'
6669
/ f'ses-{session.visit_label}'
67-
/ nifti.data_type.name
70+
/ acquisition.data_type.name
6871
)
6972

70-
loris_file_path = loris_file_dir_path / nifti.name
73+
loris_file_path = loris_file_dir_path / acquisition.nifti_path.name
7174

7275
loris_file_rel_path = loris_file_path.relative_to(import_env.data_dir_path)
7376

@@ -81,40 +84,36 @@ def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, n
8184

8285
# Get information about the file.
8386

84-
file_type = get_check_nifti_imaging_file_type(env, nifti)
85-
file_hash = get_check_nifti_file_hash(env, nifti)
86-
mri_scan_type = get_nifti_mri_scan_type(env, import_env, nifti)
87+
file_type = get_check_nifti_imaging_file_type(env, acquisition)
88+
file_hash = get_check_nifti_file_hash(env, acquisition)
89+
mri_scan_type = get_nifti_mri_scan_type(env, import_env, acquisition)
8790

8891
# Get the auxiliary files.
8992

9093
aux_file_paths: list[Path] = []
9194

92-
json_path = nifti.get_json_path()
95+
if acquisition.bval_path is not None:
96+
aux_file_paths.append(acquisition.bval_path)
9397

94-
bval_path = nifti.get_bval_path()
95-
if bval_path is not None:
96-
aux_file_paths.append(bval_path)
97-
98-
bvec_path = nifti.get_bvec_path()
99-
if bvec_path is not None:
100-
aux_file_paths.append(bvec_path)
98+
if acquisition.bvec_path is not None:
99+
aux_file_paths.append(acquisition.bvec_path)
101100

102101
# Get the file parameters.
103102

104103
file_parameters: dict[str, Any] = {}
105104

106-
if json_path is not None:
107-
json_loris_path = loris_file_dir_path / json_path.name
105+
if acquisition.sidecar_path is not None:
106+
json_loris_path = loris_file_dir_path / acquisition.sidecar_path.name
108107
json_loris_rel_path = json_loris_path.relative_to(import_env.data_dir_path)
109-
add_bids_json_file_parameters(env, json_path, json_loris_rel_path, file_parameters)
108+
add_bids_json_file_parameters(env, acquisition.sidecar_path, json_loris_rel_path, file_parameters)
110109

111-
add_nifti_file_parameters(nifti.path, file_hash, file_parameters)
110+
add_nifti_file_parameters(acquisition.nifti_path, file_hash, file_parameters)
112111

113-
if nifti.session.tsv_scans_path is not None and tsv_scan is not None:
114-
add_scan_tsv_file_parameters(tsv_scan, nifti.session.tsv_scans_path, file_parameters)
112+
if acquisition.session.tsv_scans_path is not None and tsv_scan is not None:
113+
add_scan_tsv_file_parameters(tsv_scan, acquisition.session.tsv_scans_path, file_parameters)
115114

116115
for aux_file_path in aux_file_paths:
117-
aux_file_type = get_file_extension(aux_file_path.name)
116+
aux_file_type = get_path_extension(aux_file_path)
118117
aux_file_hash = compute_file_blake2b_hash(aux_file_path)
119118
aux_file_loris_path = loris_file_dir_path / aux_file_path.name
120119
aux_file_loris_rel_path = aux_file_loris_path.relative_to(import_env.data_dir_path)
@@ -123,10 +122,10 @@ def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, n
123122

124123
# Copy the files on the file system.
125124

126-
copy_bids_file(loris_file_dir_path, nifti.path)
125+
copy_bids_file(loris_file_dir_path, acquisition.nifti_path)
127126

128-
if json_path is not None:
129-
copy_bids_file(loris_file_dir_path, json_path)
127+
if acquisition.sidecar_path is not None:
128+
copy_bids_file(loris_file_dir_path, acquisition.sidecar_path)
130129

131130
for aux_file_path in aux_file_paths:
132131
copy_bids_file(loris_file_dir_path, aux_file_path)
@@ -159,26 +158,26 @@ def import_bids_nifti(env: Env, import_env: BIDSImportEnv, session: DbSession, n
159158
import_env.imported_files_count += 1
160159

161160

162-
def get_check_nifti_imaging_file_type(env: Env, nifti: BIDSNifti) -> str:
161+
def get_check_nifti_imaging_file_type(env: Env, acqusition: BIDSMRIAcquisition) -> str:
163162
"""
164163
Get the BIDS file type of a NIfTI file and raise an exception if that file type is not
165164
registered in the database.
166165
"""
167166

168-
file_type = determine_bids_file_type(env, nifti.name)
167+
file_type = determine_bids_file_type(env, acqusition.nifti_path.name)
169168
if file_type is None:
170169
raise Exception("No matching file type found in the database.")
171170

172171
return file_type
173172

174173

175-
def get_check_nifti_file_hash(env: Env, nifti: BIDSNifti) -> str:
174+
def get_check_nifti_file_hash(env: Env, acquisition: BIDSMRIAcquisition) -> str:
176175
"""
177176
Compute the BLAKE2b hash of a NIfTI file and raise an exception if that hash is already
178177
registered in the database.
179178
"""
180179

181-
file_hash = compute_file_blake2b_hash(nifti.path)
180+
file_hash = compute_file_blake2b_hash(acquisition.nifti_path)
182181

183182
file = try_get_file_with_hash(env.db, file_hash)
184183
if file is not None:
@@ -187,27 +186,31 @@ def get_check_nifti_file_hash(env: Env, nifti: BIDSNifti) -> str:
187186
return file_hash
188187

189188

190-
def get_nifti_mri_scan_type(env: Env, import_env: BIDSImportEnv, nifti: BIDSNifti) -> DbMriScanType | None:
189+
def get_nifti_mri_scan_type(
190+
env: Env,
191+
import_env: BIDSImportEnv,
192+
acquisition: BIDSMRIAcquisition,
193+
) -> DbMriScanType | None:
191194
"""
192-
Get the MRI scan type corresponding to a NIfTI file using its BIDS suffix. Create the MRI scan
193-
type in the database the suffix is a standard BIDS suffix and the scan type does not already
194-
exist in the database, or raise an exception if no known scan type is found.
195+
Get the MRI scan type corresponding to a BIDS MRI acquisition using its BIDS suffix. Create the
196+
MRI scan type in the database the suffix is a standard BIDS suffix and the scan type does not
197+
already exist in the database, or raise an exception if no known scan type is found.
195198
"""
196199

197-
if nifti.suffix is None:
200+
if acquisition.suffix is None:
198201
raise Exception("No BIDS suffix found in the NIfTI file name, cannot infer the file data type.")
199202

200-
mri_scan_type = try_get_mri_scan_type_with_name(env.db, nifti.suffix)
203+
mri_scan_type = try_get_mri_scan_type_with_name(env.db, acquisition.suffix)
201204
if mri_scan_type is not None:
202205
return mri_scan_type
203206

204-
if nifti.suffix not in KNOWN_SUFFIXES_PER_MRI_DATA_TYPE[nifti.data_type.name]:
205-
if nifti.suffix not in import_env.unknown_scan_types:
206-
import_env.unknown_scan_types.append(nifti.suffix)
207+
if acquisition.suffix not in KNOWN_SUFFIXES_PER_MRI_DATA_TYPE[acquisition.data_type.name]:
208+
if acquisition.suffix not in import_env.unknown_scan_types:
209+
import_env.unknown_scan_types.append(acquisition.suffix)
207210

208-
raise Exception(f"Found unknown MRI file suffix '{nifti.suffix}'.")
211+
raise Exception(f"Found unknown MRI file suffix '{acquisition.suffix}'.")
209212

210-
return create_mri_scan_type(env, nifti.suffix)
213+
return create_mri_scan_type(env, acquisition.suffix)
211214

212215

213216
def copy_bids_file(loris_file_dir_path: Path, file_path: Path):

0 commit comments

Comments
 (0)