Skip to content

Commit

Permalink
rebase update_multiorient_name
Browse files Browse the repository at this point in the history
  • Loading branch information
bpinsard committed Sep 24, 2024
1 parent 383525d commit 05796fb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
41 changes: 41 additions & 0 deletions heudiconv/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,34 @@ def update_uncombined_name(
return filename


def update_multiorient_name(
metadata: dict[str, Any],
filename: str,
) -> str:
if "acq-" in filename:
lgr.warning(
"Not embedding multi-orientation information as prefix already uses acq- parameter."
)
return filename
iop = metadata.get("ImageOrientationPatientDICOM")
iop = [round(x) for x in iop]
cross_prod = [
iop[1] * iop[5] - iop[2] * iop[4],
iop[2] * iop[3] - iop[0] * iop[5],
iop[0] * iop[4] - iop[1] * iop[3],
]
cross_prod = [abs(x) for x in cross_prod]
slice_orient = ["sagittal", "coronal", "axial"][cross_prod.index(1)]
bids_pairs = filename.split("_")
# acq needs to be inserted right after sub- or ses-
ses_or_sub_idx = sum(
[bids_pair.split("-")[0] in ["sub", "ses"] for bids_pair in bids_pairs]
)
bids_pairs.insert(ses_or_sub_idx, "acq-%s" % slice_orient)
filename = "_".join(bids_pairs)
return filename


def convert(
items: list[tuple[str, tuple[str, ...], list[str]]],
converter: str,
Expand Down Expand Up @@ -953,6 +981,7 @@ def save_converted_files(
echo_times: set[float] = set()
channel_names: set[str] = set()
image_types: set[str] = set()
iops: set[str] = set()
for metadata in bids_metas:
if not metadata:
continue
Expand All @@ -968,6 +997,12 @@ def save_converted_files(
image_types.update(metadata["ImageType"])
except KeyError:
pass
try:
iops.add(str(metadata["ImageOrientationPatientDICOM"]))
except KeyError:
pass

print(iops)

is_multiecho = (
len(set(filter(bool, echo_times))) > 1
Expand All @@ -978,6 +1013,7 @@ def save_converted_files(
is_complex = (
"M" in image_types and "P" in image_types
) # Determine if data are complex (magnitude + phase)
is_multiorient = len(iops) > 1
echo_times_lst = sorted(echo_times) # also converts to list
channel_names_lst = sorted(channel_names) # also converts to list

Expand Down Expand Up @@ -1008,6 +1044,11 @@ def save_converted_files(
bids_meta, this_prefix_basename, channel_names_lst
)

if is_multiorient:
this_prefix_basename = update_multiorient_name(
bids_meta, this_prefix_basename
)

# Fallback option:
# If we have failed to modify this_prefix_basename, because it didn't fall
# into any of the options above, just add the suffix at the end:
Expand Down
13 changes: 13 additions & 0 deletions heudiconv/tests/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
bvals_are_zero,
update_complex_name,
update_multiecho_name,
update_multiorient_name,
update_uncombined_name,
)
from heudiconv.utils import load_heuristic
Expand Down Expand Up @@ -143,6 +144,18 @@ def test_update_uncombined_name() -> None:
update_uncombined_name(metadata, base_fn, set(channel_names)) # type: ignore[arg-type]


def test_update_multiorient_name() -> None:
"""Unit testing for heudiconv.convert.update_multiorient_name(), which updates
filenames with the acq field if appropriate.
"""
# Standard name update
base_fn = "sub-X_ses-Y_task-Z_run-01_bold"
metadata = {"ImageOrientationPatientDICOM": [0, 1, 0, 0, 0, -1]}
out_fn_true = "sub-X_ses-Y_acq-sagittal_task-Z_run-01_bold"
out_fn_test = update_multiorient_name(metadata, base_fn)
assert out_fn_test == out_fn_true


def test_b0dwi_for_fmap(tmp_path: Path, caplog: pytest.LogCaptureFixture) -> None:
"""Make sure we raise a warning when .bvec and .bval files
are present but the modality is not dwi.
Expand Down

0 comments on commit 05796fb

Please sign in to comment.