Skip to content
Merged
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
32 changes: 32 additions & 0 deletions CPAC/anat_preproc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,38 @@ def mri_convert(in_file, reslice_like=None, out_file=None, args=None):
return out_file


def mri_convert_reorient(in_file, orientation, out_file=None):
"""
Reorient the mgz files using mri_orient.

Parameters
----------
in_file : string
A path of mgz input file.
orientation : string
Orientation of the output file.
out_file : string
A path of mgz output file.
args : string
Arguments of mri_convert.

Returns
-------
out_file : string
A path of reoriented mgz output file.
"""
import os

if out_file is None:
out_file = in_file.split(".")[0] + "_reoriented.mgz"

cmd = "mri_convert %s %s --out_orientation %s" % (in_file, out_file, orientation)

os.system(cmd)

return out_file


def wb_command(in_file):
import os

Expand Down
29 changes: 26 additions & 3 deletions CPAC/pipeline/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from nipype.interfaces import afni
from nipype.interfaces.utility import Rename

from CPAC.anat_preproc.utils import mri_convert_reorient
from CPAC.image_utils.spatial_smoothing import spatial_smoothing
from CPAC.image_utils.statistical_transforms import (
fisher_z_score_standardize,
Expand Down Expand Up @@ -66,6 +67,7 @@
from CPAC.utils.utils import (
check_prov_for_regtool,
create_id_string,
flip_orientation_code,
get_last_prov_entry,
read_json,
write_output_json,
Expand Down Expand Up @@ -2043,9 +2045,30 @@ def ingress_freesurfer(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id):
creds_path=data_paths["creds_path"],
dl_dir=cfg.pipeline_setup["working_directory"]["path"],
)
rpool.set_data(
key, fs_ingress, "outputspec.data", {}, "", f"fs_{key}_ingress"
)
# reorient *.mgz
if outfile.endswith(".mgz"):
Comment on lines +2048 to +2049
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These

C-PAC/CPAC/pipeline/engine.py

Lines 2014 to 2018 in 325deb5

"pipeline-fs_raw-average": "mri/rawavg.mgz",
"pipeline-fs_subcortical-seg": "mri/aseg.mgz",
"pipeline-fs_brainmask": "mri/brainmask.mgz",
"pipeline-fs_wmparc": "mri/wmparc.mgz",
"pipeline-fs_T1": "mri/T1.mgz",
need reoriented but these

C-PAC/CPAC/pipeline/engine.py

Lines 2019 to 2035 in 325deb5

"pipeline-fs_hemi-L_desc-surface_curv": "surf/lh.curv",
"pipeline-fs_hemi-R_desc-surface_curv": "surf/rh.curv",
"pipeline-fs_hemi-L_desc-surfaceMesh_pial": "surf/lh.pial",
"pipeline-fs_hemi-R_desc-surfaceMesh_pial": "surf/rh.pial",
"pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm": "surf/lh.smoothwm",
"pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm": "surf/rh.smoothwm",
"pipeline-fs_hemi-L_desc-surfaceMesh_sphere": "surf/lh.sphere",
"pipeline-fs_hemi-R_desc-surfaceMesh_sphere": "surf/rh.sphere",
"pipeline-fs_hemi-L_desc-surfaceMap_sulc": "surf/lh.sulc",
"pipeline-fs_hemi-R_desc-surfaceMap_sulc": "surf/rh.sulc",
"pipeline-fs_hemi-L_desc-surfaceMap_thickness": "surf/lh.thickness",
"pipeline-fs_hemi-R_desc-surfaceMap_thickness": "surf/rh.thickness",
"pipeline-fs_hemi-L_desc-surfaceMap_volume": "surf/lh.volume",
"pipeline-fs_hemi-R_desc-surfaceMap_volume": "surf/rh.volume",
"pipeline-fs_hemi-L_desc-surfaceMesh_white": "surf/lh.white",
"pipeline-fs_hemi-R_desc-surfaceMesh_white": "surf/rh.white",
"pipeline-fs_xfm": "mri/transforms/talairach.lta",
don't, is that right?

Copy link
Contributor Author

@birajstha birajstha Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question ! It looks like all pipeline-fs_hemi* are not used in CPAC but are only ingressed.
I am not sure about pipeline-fs_xfm. It probably needs reorient/resample as well.
I will loop in @sgiavasis here for further clarification.
Steve, do we need to resample this xfm?
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've had extensive conversation on this off of GitHub, but going forward from here, let's resolve whatever requested changes there are and merge this.

For the reorient for running Freesurfer as part of the C-PAC pipeline, let's open a separate but related PR for it, as it will be an extension of this one but different.
I'd like to get some runs going with this change for now (since it will be ingressed).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am adding this below for documentation purposes.
Tested applying the xfm mentioned above to wmparc from

  1. Freesurfer native orientation

image
and
2. reoriented one from this PR
image

There appears to be no difference in the output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So reorienting only .mgz files.

reorient_mgz = pe.Node(
Function(
input_names=["in_file", "orientation", "out_file"],
output_names=["out_file"],
function=mri_convert_reorient,
),
name=f"reorient_mgz_{key}",
)
# Flip orientation before reorient because mri_convert's orientation is opposite that of AFNI
reorient_mgz.inputs.orientation = flip_orientation_code(
cfg.pipeline_setup["desired_orientation"]
)
reorient_mgz.inputs.out_file = None
wf.connect(fs_ingress, "outputspec.data", reorient_mgz, "in_file")

rpool.set_data(
key, reorient_mgz, "out_file", {}, "", f"fs_{key}_ingress"
)
else:
rpool.set_data(
key, fs_ingress, "outputspec.data", {}, "", f"fs_{key}_ingress"
)
else:
warnings.warn(
str(LookupError(f"\n[!] Path does not exist for {fullpath}.\n"))
Expand Down
8 changes: 8 additions & 0 deletions CPAC/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2631,3 +2631,11 @@ def _replace_in_value_list(current_value, replacement_tuple):
for v in current_value
if bool(v) and v not in {"None", "Off", ""}
]


def flip_orientation_code(code):
"""
Reverts an orientation code by flipping R↔L, A↔P, and I↔S.
"""
flip_dict = {"R": "L", "L": "R", "A": "P", "P": "A", "I": "S", "S": "I"}
return "".join(flip_dict[c] for c in code)