Skip to content

Commit e4e4a5a

Browse files
committed
wip 2
1 parent f633d8e commit e4e4a5a

34 files changed

Lines changed: 556 additions & 312 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ preview = true
5757

5858
[tool.ruff.lint]
5959
ignore = ["E202", "E203", "E221", "E241", "E251", "E272"]
60-
select = ["E", "EXE", "F", "I", "N", "RUF", "UP", "W"]
60+
select = ["E", "EXE", "F", "FAST", "I", "N", "RUF", "UP", "W"]
6161

6262
[tool.ruff.lint.pycodestyle]
6363
max-doc-length = 100

python/lib/config.py

Lines changed: 42 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,7 @@ def get_data_dir_path_config(env: Env) -> Path:
3434
"""
3535

3636
data_dir_path = Path(_get_config_value(env, 'dataDirBasepath'))
37-
38-
if not data_dir_path.is_dir():
39-
log_error_exit(
40-
env,
41-
(
42-
f"The LORIS base data directory path configuration value '{data_dir_path}' does not refer to an"
43-
" existing directory."
44-
)
45-
)
46-
47-
if not os.access(data_dir_path, os.R_OK) or not os.access(data_dir_path, os.W_OK):
48-
log_error_exit(
49-
env,
50-
f"Missing read or write permission on the LORIS base data directory '{data_dir_path}'.",
51-
)
52-
37+
check_loris_directory(env, data_dir_path, "data")
5338
return data_dir_path
5439

5540

@@ -60,22 +45,7 @@ def get_dicom_archive_dir_path_config(env: Env) -> Path:
6045
"""
6146

6247
dicom_archive_dir_path = Path(_get_config_value(env, 'tarchiveLibraryDir'))
63-
64-
if not dicom_archive_dir_path.is_dir():
65-
log_error_exit(
66-
env,
67-
(
68-
f"The LORIS DICOM archive directory path configuration value '{dicom_archive_dir_path}' does not refer"
69-
" to an existing directory."
70-
),
71-
)
72-
73-
if not os.access(dicom_archive_dir_path, os.R_OK) or not os.access(dicom_archive_dir_path, os.W_OK):
74-
log_error_exit(
75-
env,
76-
f"Missing read or write permission on the LORIS DICOM archive directory '{dicom_archive_dir_path}'.",
77-
)
78-
48+
check_loris_directory(env, dicom_archive_dir_path, "DICOM archive")
7949
return dicom_archive_dir_path
8050

8151

@@ -87,74 +57,43 @@ def get_default_bids_visit_label_config(env: Env) -> str | None:
8757
return _try_get_config_value(env, 'default_bids_vl')
8858

8959

90-
def get_eeg_viz_enabled_config(env: Env) -> bool:
60+
def get_ephys_visualization_enabled_config(env: Env) -> bool:
9161
"""
92-
Get whether the EEG visualization is enabled from the in-database configuration.
62+
Get whether the electrophysiology visualization is enabled from the in-database configuration.
9363
"""
9464

9565
eeg_viz_enabled = _try_get_config_value(env, 'useEEGBrowserVisualizationComponents')
9666
return eeg_viz_enabled == 'true' or eeg_viz_enabled == '1'
9767

9868

99-
def get_eeg_chunks_dir_path_config(env: Env) -> Path | None:
69+
def get_ephys_chunks_dir_path_config(env: Env) -> Path | None:
10070
"""
101-
Get the EEG chunks directory path configuration value from the in-database configuration.
71+
Get the electrophysiology chunks directory path configuration value from the in-database
72+
configuration.
10273
"""
10374

104-
eeg_chunks_path = _try_get_config_value(env, 'EEGChunksPath')
105-
if eeg_chunks_path is None:
75+
ephys_chunks_path = _try_get_config_value(env, 'EEGChunksPath')
76+
if ephys_chunks_path is None:
10677
return None
10778

108-
eeg_chunks_path = Path(eeg_chunks_path)
109-
110-
if not eeg_chunks_path.is_dir():
111-
log_error_exit(
112-
env,
113-
(
114-
f"The configuration value for the LORIS EEG chunks directory path '{eeg_chunks_path}' does not refer to"
115-
" an existing directory."
116-
),
117-
)
118-
119-
if not os.access(eeg_chunks_path, os.R_OK) or not os.access(eeg_chunks_path, os.W_OK):
120-
log_error_exit(
121-
env,
122-
f"Missing read or write permission on the LORIS EEG chunks directory '{eeg_chunks_path}'.",
123-
)
124-
125-
return eeg_chunks_path
79+
ephys_chunks_path = Path(ephys_chunks_path)
80+
check_loris_directory(env, ephys_chunks_path, "electrophysiology chunks")
81+
return ephys_chunks_path
12682

12783

128-
def get_eeg_pre_package_download_dir_path_config(env: Env) -> Path | None:
84+
def get_ephys_archive_dir_path_config(env: Env) -> Path | None:
12985
"""
130-
Get the EEG pre-packaged download path configuration value from the in-database configuration.
86+
Get the electrophysiology archive directory path configuration value from the in-database
87+
configuration.
13188
"""
13289

133-
eeg_pre_package_path = _try_get_config_value(env, 'prePackagedDownloadPath')
134-
if eeg_pre_package_path is None:
90+
ephys_archive_dir_path = _try_get_config_value(env, 'prePackagedDownloadPath')
91+
if ephys_archive_dir_path is None:
13592
return None
13693

137-
eeg_pre_package_path = Path(eeg_pre_package_path)
138-
139-
if not eeg_pre_package_path.is_dir():
140-
log_error_exit(
141-
env,
142-
(
143-
"The configuration value for the LORIS EEG pre-packaged download directory path"
144-
f" '{eeg_pre_package_path}' does not refer to an existing directory."
145-
),
146-
)
147-
148-
if not os.access(eeg_pre_package_path, os.R_OK) or not os.access(eeg_pre_package_path, os.W_OK):
149-
log_error_exit(
150-
env,
151-
(
152-
"Missing read or write permission on the LORIS EEG pre-packaged download directory"
153-
f" '{eeg_pre_package_path}'."
154-
),
155-
)
156-
157-
return eeg_pre_package_path
94+
ephys_archive_dir_path = Path(ephys_archive_dir_path)
95+
check_loris_directory(env, ephys_archive_dir_path, "electrophysiology archive")
96+
return ephys_archive_dir_path
15897

15998

16099
def _get_config_value(env: Env, setting_name: str) -> str:
@@ -179,6 +118,28 @@ def _get_config_value(env: Env, setting_name: str) -> str:
179118
return config.value
180119

181120

121+
def check_loris_directory(env: Env, dir_path: Path, display_name: str):
122+
"""
123+
Check that a LORIS directory exists and is readable and writable, or exit the program with an
124+
error otherwise.
125+
"""
126+
127+
if not dir_path.is_dir():
128+
log_error_exit(
129+
env,
130+
(
131+
f"The LORIS {display_name} directory path configuration value '{dir_path}' does not refer to an"
132+
" existing directory."
133+
),
134+
)
135+
136+
if not os.access(dir_path, os.R_OK) or not os.access(dir_path, os.W_OK):
137+
log_error_exit(
138+
env,
139+
f"Missing read or write permission on the {display_name} directory '{dir_path}'.",
140+
)
141+
142+
182143
def _try_get_config_value(env: Env, setting_name: str) -> str | None:
183144
"""
184145
Get a configuration value from the database using a configuration setting name, or return

python/lib/eeg.py

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

1515
import lib.exitcode
1616
import lib.utilities as utilities
17-
from lib.config import get_eeg_viz_enabled_config
17+
from lib.config import get_ephys_visualization_enabled_config
1818
from lib.db.models.physio_file import DbPhysioFile
1919
from lib.db.models.session import DbSession
2020
from lib.db.queries.physio_file import try_get_physio_file_with_path
@@ -206,7 +206,7 @@ def register_data(self, derivatives=False, detect=True):
206206
import_physio_file_archive(self.env, eeg_file, files_to_archive)
207207

208208
# create data chunks for React visualization
209-
if get_eeg_viz_enabled_config(self.env):
209+
if get_ephys_visualization_enabled_config(self.env):
210210
create_physio_channels_chunks(self.env, eeg_file)
211211

212212
def fetch_and_insert_eeg_files(self, derivatives=False, detect=True):

python/lib/import_bids_dataset/archive.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from loris_utils.crypto import compute_file_blake2b_hash
55
from loris_utils.path import remove_path_extension
66

7-
from lib.config import get_data_dir_path_config, get_eeg_pre_package_download_dir_path_config
7+
from lib.config import get_data_dir_path_config, get_ephys_archive_dir_path_config
88
from lib.db.models.physio_event_archive import DbPhysioEventArchive
99
from lib.db.models.physio_file import DbPhysioFile
1010
from lib.db.models.physio_file_archive import DbPhysioFileArchive
@@ -70,9 +70,9 @@ def get_archive_path(env: Env, file_path: Path) -> Path:
7070
"""
7171

7272
archive_rel_path = remove_path_extension(file_path).with_suffix('.tgz')
73-
archives_dir_path = get_eeg_pre_package_download_dir_path_config(env)
74-
if archives_dir_path is not None:
73+
archive_dir_path = get_ephys_archive_dir_path_config(env)
74+
if archive_dir_path is not None:
7575
data_dir_path = get_data_dir_path_config(env)
76-
return (archives_dir_path / 'raw' / archive_rel_path.name).relative_to(data_dir_path)
76+
return (archive_dir_path / 'raw' / archive_rel_path.name).relative_to(data_dir_path)
7777
else:
7878
return archive_rel_path

python/lib/import_bids_dataset/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
)
2424
from lib.import_bids_dataset.env import BidsImportEnv
2525
from lib.import_bids_dataset.events import get_root_events_metadata
26-
from lib.import_bids_dataset.meg import import_bids_meg_data_type
26+
from lib.import_bids_dataset.meg.ctf import import_bids_meg_data_type
2727
from lib.import_bids_dataset.mri import import_bids_mri_data_type
2828
from lib.import_bids_dataset.print import print_bids_import_summary
2929
from lib.logging import log, log_error_exit, log_warning
@@ -93,7 +93,7 @@ def import_bids_dataset(env: Env, args: Args, legacy_db: Database):
9393

9494
import_env = BidsImportEnv(
9595
data_dir_path = data_dir_path,
96-
loris_bids_path = loris_bids_path,
96+
loris_bids_path = loris_bids_path.relative_to(data_dir_path) if loris_bids_path is not None else None,
9797
total_files_count = acquisitions_count,
9898
)
9999

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33
from loris_bids_reader.info import BidsAcquisitionInfo
44
from loris_bids_reader.meg.acquisition import MegAcquisition
55
from loris_bids_reader.meg.reader import BidsMegDataTypeReader
6+
from loris_utils.archive import create_archive_with_file
67
from loris_utils.error import group_errors_tuple
8+
from loris_utils.path import add_path_extension
79

8-
from lib.config import get_eeg_viz_enabled_config
10+
from lib.config import (
11+
get_data_dir_path_config,
12+
get_ephys_archive_dir_path_config,
13+
get_ephys_visualization_enabled_config,
14+
)
915
from lib.db.models.meg_ctf_head_shape_file import DbMegCtfHeadShapeFile
1016
from lib.db.models.session import DbSession
1117
from lib.db.queries.physio_file import try_get_physio_file_with_path
@@ -18,9 +24,12 @@
1824
from lib.import_bids_dataset.events import insert_events_metadata_file
1925
from lib.import_bids_dataset.events_tsv import insert_bids_events_file
2026
from lib.import_bids_dataset.file_type import get_check_bids_imaging_file_type
21-
from lib.import_bids_dataset.head_shape import insert_head_shape_file
22-
from lib.import_bids_dataset.meg_channels import read_meg_channels
23-
from lib.import_bids_dataset.physio import get_check_bids_physio_modality, get_check_bids_physio_output_type
27+
from lib.import_bids_dataset.meg.ctf_head_shape import insert_head_shape_file
28+
from lib.import_bids_dataset.physio import (
29+
get_check_bids_physio_file_hash,
30+
get_check_bids_physio_modality,
31+
get_check_bids_physio_output_type,
32+
)
2433
from lib.logging import log, log_warning
2534
from lib.physio.chunking import create_physio_channels_chunks
2635
from lib.physio.events import FileSource
@@ -73,13 +82,12 @@ def import_bids_meg_acquisition(
7382
bids_info: BidsAcquisitionInfo,
7483
head_shape_file: DbMegCtfHeadShapeFile | None,
7584
):
76-
# TODO: The file is actually a directory, it should be tared before proceeding to the hash.
77-
modality, output_type, file_type = group_errors_tuple(
85+
modality, output_type, file_type, file_hash = group_errors_tuple(
7886
f"Error while checking database information for MEG acquisition '{bids_info.name}'.",
7987
lambda: get_check_bids_physio_modality(env, bids_info.data_type),
8088
lambda: get_check_bids_physio_output_type(env, args.type or 'raw'),
8189
lambda: get_check_bids_imaging_file_type(env, 'ctf'),
82-
# lambda: get_check_bids_physio_file_hash(env, acquisition),
90+
lambda: get_check_bids_physio_file_hash(env, acquisition.ctf_path),
8391
)
8492

8593
# The files to copy to LORIS, with the source path on the left and the LORIS path on the right.
@@ -96,6 +104,9 @@ def import_bids_meg_acquisition(
96104

97105
check_bids_meg_metadata_files(env, acquisition, bids_info)
98106

107+
ctf_archive_path = get_ctf_archive_path(env, loris_file_path)
108+
create_archive_with_file(import_env.data_dir_path / ctf_archive_path, acquisition.ctf_path)
109+
99110
physio_file = insert_physio_file(
100111
env,
101112
session,
@@ -104,11 +115,11 @@ def import_bids_meg_acquisition(
104115
modality,
105116
output_type,
106117
bids_info.scan_row.get_acquisition_time() if bids_info.scan_row is not None else None,
107-
None, # TODO: Use archive.
118+
ctf_archive_path,
108119
head_shape_file,
109120
)
110121

111-
# insert_physio_file_parameter(env, physio_file, 'physiological_json_file_blake2b_hash', file_hash) # ruff:noqa
122+
insert_physio_file_parameter(env, physio_file, 'physiological_file_blake2b_hash', file_hash)
112123
for name, value in acquisition.sidecar_file.data.items():
113124
insert_physio_file_parameter(env, physio_file, name, value)
114125

@@ -139,17 +150,12 @@ def import_bids_meg_acquisition(
139150

140151
log(env, f"MEG file succesfully imported with ID: {physio_file.id}.")
141152

142-
# TODO: Remove the false.
143-
if get_eeg_viz_enabled_config(env):
153+
if get_ephys_visualization_enabled_config(env):
144154
log(env, "Creating visualization chunks...")
145155
create_physio_channels_chunks(env, physio_file)
146156

147-
read_meg_channels(env, import_env, physio_file, acquisition, bids_info)
148-
149157
env.db.commit()
150158

151-
import_env.imported_files_count += 1
152-
153159

154160
def check_bids_meg_metadata_files(env: Env, acquisition: MegAcquisition, bids_info: BidsAcquisitionInfo):
155161
"""
@@ -165,3 +171,19 @@ def check_bids_meg_metadata_files(env: Env, acquisition: MegAcquisition, bids_in
165171

166172
if acquisition.events_file is not None and acquisition.events_file.dictionary is not None:
167173
log_warning(env, f"No events dictionary file found for acquisition '{bids_info.name}'.")
174+
175+
176+
def get_ctf_archive_path(env: Env, loris_ctf_path: Path) -> Path:
177+
"""
178+
Get the path of a CTF archive.
179+
"""
180+
181+
archive_rel_path = add_path_extension(loris_ctf_path, 'tgz')
182+
archive_dir_path = get_ephys_archive_dir_path_config(env)
183+
if archive_dir_path is not None:
184+
data_dir_path = get_data_dir_path_config(env)
185+
archive_path = archive_dir_path / 'ctf' / archive_rel_path.name
186+
archive_path.parent.mkdir(exist_ok=True, parents=True)
187+
return (archive_path).relative_to(data_dir_path)
188+
else:
189+
return archive_rel_path

python/lib/import_bids_dataset/head_shape.py renamed to python/lib/import_bids_dataset/meg/ctf_head_shape.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ def insert_head_shape_file(
2727
env.db.add(db_head_shape_file)
2828
env.db.flush()
2929

30-
for name, coordinates in head_shape_file.points.items():
30+
for name, point in head_shape_file.points.items():
3131
env.db.add(DbMegCtfHeadShapePoint(
3232
file_id = db_head_shape_file.id,
3333
name = name,
34-
x = coordinates.x,
35-
y = coordinates.y,
36-
z = coordinates.z,
34+
x = point.x,
35+
y = point.y,
36+
z = point.z,
3737
))
3838

3939
env.db.flush()

0 commit comments

Comments
 (0)