From 8cf61335d6c64e2b23ae640480cbfdc1b048189b Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 5 Aug 2024 17:10:31 +0200 Subject: [PATCH] fix missing repetition time (#218) --- bidsmreye/bids_utils.py | 17 +++++++++-------- bidsmreye/generalize.py | 9 ++++----- bidsmreye/prepare_data.py | 26 +++++++++++++++----------- bidsmreye/quality_control.py | 3 +-- bidsmreye/utils.py | 9 ++++++--- bidsmreye/visualize.py | 9 ++++----- pyproject.toml | 1 + tests/test_bids_utils.py | 3 +-- 8 files changed, 41 insertions(+), 36 deletions(-) diff --git a/bidsmreye/bids_utils.py b/bidsmreye/bids_utils.py index 2a97344..cc1dfab 100644 --- a/bidsmreye/bids_utils.py +++ b/bidsmreye/bids_utils.py @@ -4,8 +4,8 @@ from pathlib import Path from typing import Any -import nibabel as nib from bids import BIDSLayout # type: ignore +from bids.layout import BIDSFile from bidsmreye._version import __version__ from bidsmreye.configuration import ( @@ -143,15 +143,16 @@ def create_sidecar( def save_sampling_frequency_to_json( - layout_out: BIDSLayout, img: str, source: str + layout_out: BIDSLayout, img: BIDSFile, source: str ) -> None: - func_img = nib.load(img) - header = func_img.header - sampling_frequency = header.get_zooms()[3] - if sampling_frequency <= 1: - log.warning(f"Found a repetition time of {sampling_frequency} seconds.") + metadata = img.get_metadata() + repetition_time = metadata["RepetitionTime"] + # TODO handle rare edge case where preprocessed data + # does not contain RepetitionTime metadata + if repetition_time <= 1: + log.warning(f"Found a repetition time of {repetition_time} seconds.") create_sidecar( - layout_out, img, SamplingFrequency=1 / float(sampling_frequency), source=source + layout_out, img.path, SamplingFrequency=1 / float(repetition_time), source=source ) diff --git a/bidsmreye/generalize.py b/bidsmreye/generalize.py index 41aefea..45f7b00 100644 --- a/bidsmreye/generalize.py +++ b/bidsmreye/generalize.py @@ -158,7 +158,6 @@ def process_subject(cfg: Config, layout_out: BIDSLayout, subject_label: str) -> this_filter = set_this_filter(cfg, subject_label, "no_label") bf = layout_out.get( - return_type="filename", regex_search=True, **this_filter, ) @@ -166,11 +165,11 @@ def process_subject(cfg: Config, layout_out: BIDSLayout, subject_label: str) -> check_if_file_found(bf, this_filter, layout_out) for file in bf: - log.info(f"Processing file: {Path(file).name}") + log.info(f"Processing file: {Path(file.path).name}") print("\n") - generators = data_generator.create_generators([file], [file]) - generators = (*generators, [file], [file]) + generators = data_generator.create_generators([file.path], [file.path]) + generators = (*generators, [file.path], [file.path]) print("\n") opts = model_opts.get_opts() @@ -200,7 +199,7 @@ def process_subject(cfg: Config, layout_out: BIDSLayout, subject_label: str) -> percentile_cut=80, ) - create_confounds_tsv(layout_out, file, subject_label) + create_confounds_tsv(layout_out, file.path, subject_label) def generalize(cfg: Config) -> None: diff --git a/bidsmreye/prepare_data.py b/bidsmreye/prepare_data.py index bc983d9..3cba8ca 100644 --- a/bidsmreye/prepare_data.py +++ b/bidsmreye/prepare_data.py @@ -8,6 +8,7 @@ import numpy as np from bids import BIDSLayout # type: ignore +from bids.layout import BIDSFile from deepmreye import preprocess from bidsmreye.bids_utils import ( @@ -131,7 +132,6 @@ def process_subject( this_filter = set_this_filter(cfg, subject_label, "bold") bf = layout_in.get( - return_type="filename", regex_search=True, **this_filter, ) @@ -143,12 +143,14 @@ def process_subject( def prepapre_image( - cfg: Config, layout_in: BIDSLayout, layout_out: BIDSLayout, img: str + cfg: Config, layout_in: BIDSLayout, layout_out: BIDSLayout, img: BIDSFile ) -> None: """Preprocess a single functional image.""" - report_name = create_bidsname(layout_out, filename=img, filetype="report") - mask_name = create_bidsname(layout_out, filename=img, filetype="mask") - output_file = create_bidsname(layout_out, Path(img), "no_label") + img_path = img.path + + report_name = create_bidsname(layout_out, filename=img_path, filetype="report") + mask_name = create_bidsname(layout_out, filename=img_path, filetype="mask") + output_file = create_bidsname(layout_out, Path(img_path), "no_label") if ( not cfg.force @@ -159,21 +161,23 @@ def prepapre_image( log.debug( "Output for the following file already exists. " "Use the '--force' option to overwrite. " - f"\n '{Path(img).name}'" + f"\n '{Path(img_path).name}'" ) return - log.info(f"Processing file: {Path(img).name}") + log.info(f"Processing file: {Path(img_path).name}") - coregister_and_extract_data(img, non_linear_coreg=cfg.non_linear_coreg) + coregister_and_extract_data(img_path, non_linear_coreg=cfg.non_linear_coreg) - deepmreye_mask_report = get_deepmreye_filename(layout_in, img=img, filetype="report") + deepmreye_mask_report = get_deepmreye_filename( + layout_in, img=img_path, filetype="report" + ) move_file(deepmreye_mask_report, report_name) - deepmreye_mask_name = get_deepmreye_filename(layout_in, img=img, filetype="mask") + deepmreye_mask_name = get_deepmreye_filename(layout_in, img=img_path, filetype="mask") move_file(deepmreye_mask_name, mask_name) - source = str(Path(img).relative_to(layout_in.root)) + source = str(Path(img_path).relative_to(layout_in.root)) save_sampling_frequency_to_json(layout_out, img=img, source=source) combine_data_with_empty_labels(layout_out, mask_name) diff --git a/bidsmreye/quality_control.py b/bidsmreye/quality_control.py index 5b22719..e8df3ea 100644 --- a/bidsmreye/quality_control.py +++ b/bidsmreye/quality_control.py @@ -218,7 +218,6 @@ def qc_subject( this_filter = set_this_filter(cfg, subject_label, "eyetrack") bf = layout_in.get( - return_type="filename", regex_search=True, **this_filter, ) @@ -226,7 +225,7 @@ def qc_subject( check_if_file_found(bf, this_filter, layout_in) for file in bf: - perform_quality_control(cfg, layout_in, file, layout_out) + perform_quality_control(cfg, layout_in, file.path, layout_out) def compute_robust_outliers( diff --git a/bidsmreye/utils.py b/bidsmreye/utils.py index be77500..4f66250 100644 --- a/bidsmreye/utils.py +++ b/bidsmreye/utils.py @@ -7,6 +7,7 @@ from typing import Any from bids import BIDSLayout # type: ignore +from bids.layout import BIDSFile from rich.progress import ( BarColumn, MofNCompleteColumn, @@ -63,11 +64,13 @@ def add_sidecar_in_root(layout_out: BIDSLayout) -> None: json.dump(content, open(sidecar_name, "w"), indent=4) -def check_if_file_found(bf: Any, this_filter: dict[str, Any], layout: BIDSLayout) -> None: - if len(bf) == 0: +def check_if_file_found( + bf: list[BIDSFile], this_filter: dict[str, Any], layout: BIDSLayout +) -> None: + if not bf: log.warning(f"No file found for filter {this_filter}") else: - to_print = [str(Path(x).relative_to(layout.root)) for x in bf] + to_print = [str(Path(x.path).relative_to(layout.root)) for x in bf] log.debug(f"Found files\n{to_print}") diff --git a/bidsmreye/visualize.py b/bidsmreye/visualize.py index d4f9305..580b7d1 100644 --- a/bidsmreye/visualize.py +++ b/bidsmreye/visualize.py @@ -54,7 +54,6 @@ def collect_group_qc_data(cfg: Config) -> pd.DataFrame | None: this_filter = set_this_filter(cfg, subjects, "eyetrack_qc") bf = layout.get( - return_type="filename", regex_search=True, **this_filter, ) @@ -63,17 +62,17 @@ def collect_group_qc_data(cfg: Config) -> pd.DataFrame | None: qc_data = None for i, file in enumerate(bf): - log.info(f"Processing file: {file}") + log.info(f"Processing file: {file.path}") - entities = layout.parse_file_entities(file) + entities = layout.parse_file_entities(file.path) - with open(file) as f: + with open(file.path) as f: data = json.loads(f.read()) print(data) df = pd.json_normalize(data) - df["filename"] = Path(file).name + df["filename"] = Path(file.path).name df["subject"] = entities["subject"] qc_data = df if i == 0 else pd.concat([qc_data, df], sort=False) diff --git a/pyproject.toml b/pyproject.toml index 899b4ea..04fb59c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -156,6 +156,7 @@ module = [ ignore_missing_imports = true module = [ 'attrs.*', + 'bids.layout.*', "bidsmreye._version", 'chevron.*', 'deepmreye.*', diff --git a/tests/test_bids_utils.py b/tests/test_bids_utils.py index c0eb310..900fd46 100644 --- a/tests/test_bids_utils.py +++ b/tests/test_bids_utils.py @@ -82,13 +82,12 @@ def test_save_sampling_frequency_to_json(data_dir, pybids_test_dataset): this_filter = set_this_filter(cfg, "01", "bold") bf = layout_in.get( - return_type="filename", regex_search=True, **this_filter, ) source = "foo" save_sampling_frequency_to_json(layout_in, bf[0], source) - sidecar_name = create_bidsname(layout_in, bf[0], "confounds_json") + sidecar_name = create_bidsname(layout_in, bf[0].path, "confounds_json") with open(sidecar_name) as f: content = json.load(f) assert content["Sources"][0] == "foo"