Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple converted file sliceorientationpatient #441

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions heudiconv/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,26 @@ def update_uncombined_name(
return filename


def update_multiorient_name(bids_meta, this_prefix_basename):
if 'acq-' in this_prefix_basename:
lgr.warning('Not embedding multi-orientation information as prefix already uses acq- parameter.')
return this_prefix_basename
iop = bids_meta.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 = this_prefix_basename.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)
this_prefix_basename = '_'.join(bids_pairs)
return this_prefix_basename


def convert(
items: list[tuple[str, tuple[str, ...], list[str]]],
converter: str,
Expand Down Expand Up @@ -977,6 +997,14 @@ def save_converted_files(
echo_times_lst = sorted(echo_times) # also converts to list
channel_names_lst = sorted(channel_names) # also converts to list

iops = sorted(list(set(
str(b.get('ImageOrientationPatientDICOM', ''))
for b in bids_metas
if b
)))

is_multiorient = len(iops) > 1

### Loop through the bids_files, set the output name and save files
for fl, suffix, bids_file, bids_meta in zip(
res_files, suffixes, bids_files, bids_metas
Expand Down Expand Up @@ -1004,6 +1032,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
11 changes: 11 additions & 0 deletions heudiconv/tests/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
update_complex_name,
update_multiecho_name,
update_uncombined_name,
update_multiorient_name,
)
from heudiconv.utils import load_heuristic

Expand Down Expand Up @@ -141,6 +142,16 @@ def test_update_uncombined_name() -> None:
with pytest.raises(TypeError):
update_uncombined_name(metadata, base_fn, set(channel_names)) # type: ignore[arg-type]

def test_update_multiorient_name():
"""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
Expand Down