The focus is on visual grepping, ie. printing a few lines for each subject to get an overview of the situation. We require JSON sidecars to be present (to have been gotten).
63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
# /// script
|
|
# dependencies = ["rich"]
|
|
# ///
|
|
#
|
|
# This script prints (in color) which field maps were matched to which
|
|
# acquisition. See arguments (or --help) for details.
|
|
|
|
import argparse
|
|
from collections import defaultdict
|
|
import json
|
|
from pathlib import Path, PurePosixPath
|
|
|
|
from rich.console import Console
|
|
from rich.theme import Theme
|
|
|
|
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
parser.add_argument("modality", help="Modality label, likely func or dwi")
|
|
parser.add_argument("ds_path", help="Path to BIDS dataset")
|
|
parser.add_argument("--session", default="001", help="Session label")
|
|
parser.add_argument("--theme", default="mocha", choices=["mocha", "latte"], help="Color theme ('mocha' - dark, 'latte' - light)")
|
|
args = parser.parse_args()
|
|
|
|
ses_label = args.session
|
|
mod_label = args.modality
|
|
ds_path = args.ds_path
|
|
|
|
# a color display for visual grepping
|
|
if args.theme == "mocha":
|
|
custom_theme = Theme({"info": "#cdd6f4", "warning": "#fab387", "danger": "#f38ba8"})
|
|
else:
|
|
custom_theme = Theme({"info": "#4c4f69", "warning": "#fe640b", "danger": "#d20f39"})
|
|
console = Console(theme=custom_theme)
|
|
|
|
# loop through subjects
|
|
ds_path = Path("q01-bids-dataset")
|
|
|
|
for sub_label in sorted([p.name[4:] for p in ds_path.glob("sub-*")]):
|
|
# print a rule
|
|
console.rule(sub_label)
|
|
# get a mapping of acquisitions to field maps
|
|
fmap_dict = defaultdict(list)
|
|
for jpath in (ds_path / f"sub-{sub_label}" / f"ses-{ses_label}" / "fmap").glob("*.json"):
|
|
if jpath.is_file():
|
|
with jpath.open() as fp:
|
|
fm_sidecar = json.load(fp)
|
|
for what in fm_sidecar.get("IntendedFor", []):
|
|
fmap_dict[PurePosixPath(what).name].append(jpath.name)
|
|
else:
|
|
console.print(f"Can't read {jpath.name}", style="warning")
|
|
|
|
# get a list of acquisitions
|
|
acq = sorted([p.name for p in (ds_path / f"sub-{sub_label}" / f"ses-{ses_label}" / mod_label).glob("*.nii.gz")])
|
|
|
|
# for each acquisition, display field maps
|
|
for fn in acq:
|
|
matching_fieldmaps = sorted(fmap_dict[fn])
|
|
if len(matching_fieldmaps) == 2:
|
|
style = "info"
|
|
elif len(matching_fieldmaps) > 0:
|
|
style = "warning"
|
|
else:
|
|
style = "danger"
|
|
console.print(f"{fn} ← {', '.join(sorted(fmap_dict[fn]))}", style=style)
|