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

Fix spm native #231

Merged
merged 8 commits into from
Nov 17, 2023
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
6 changes: 3 additions & 3 deletions .github/workflows/build_on_prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ jobs:

- name: Running test pipeline macaque_prime-de
run: |
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/macaque_prime-de/ -out /data/macaque_prime-de/results -soft ${{ matrix.soft }}_prep -species macaque -sub 032140 -ses 001 -deriv -pad
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/macaque_prime-de/ -out /data/macaque_prime-de/results -soft ${{ matrix.soft }} -species macaque -sub 032140 -ses 001 -deriv -pad

- name: Running test pipeline marmo-marmobrain
run: |
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/marmo-marmobrain -out /data/marmo-marmobrain/results -soft ${{ matrix.soft }}_prep -species marmo -sub Percy -ses 01 -deriv -pad
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/marmo-marmobrain -out /data/marmo-marmobrain/results -soft ${{ matrix.soft }} -species marmo -sub Percy -ses 01 -deriv -pad

- name: Running test pipeline baboon-cerimed-adrien
run: |
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/baboon-cerimed-adrien -out /data/baboon-cerimed-adrien/results -soft ${{ matrix.soft }}_prep -species baboon -sub Fidji -ses 01 -deriv -pad
docker run -i -v /home/ubuntu/actions-runner/_work/macapype/macapype/${{ matrix.soft }}/macapype_CI:/data macatools/macapype:latest segment_pnh -data /data/baboon-cerimed-adrien -out /data/baboon-cerimed-adrien/results -soft ${{ matrix.soft }} -species baboon -sub Fidji -ses 01 -deriv -pad

- name: Cleaning dataset
run:
Expand Down
20 changes: 0 additions & 20 deletions macapype/nodes/surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,6 @@ def wrap_nii2mesh(nii_file):
assert ret == 0, "Error, cmd {} did not work".format(cmd)
return stl_file

def wrap_afni_IsoSurface (nii_file):

import os
from nipype.utils.filemanip import split_filename as split_f

path, fname, ext = split_f(nii_file)

stl_file = os.path.abspath(fname + ".stl")

isoval=1
cmd = "IsoSurface -isoval {} -input {} -Tsmooth 0.1 100 -remesh 0.5 -overwrite -autocrop -o {}".format(
isoval, nii_file, stl_file)

ret = os.system(cmd)

print(ret)

assert ret == 0, "Error, cmd {} did not work".format(cmd)
return stl_file


# ### wrapping afni IsoSurface
def wrap_afni_IsoSurface(nii_file):
Expand Down
67 changes: 66 additions & 1 deletion macapype/pipelines/full_pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
create_extract_T1_pipe)

from .surface import (create_nii_to_mesh_pipe, create_nii_to_mesh_fs_pipe,
create_nii2mesh_brain_pipe)
create_nii2mesh_brain_pipe, create_IsoSurface_brain_pipe)

from macapype.utils.misc import parse_key, list_input_files, show_files

Expand Down Expand Up @@ -2628,6 +2628,38 @@ def create_full_ants_subpipes(

seg_pipe.connect(nii2mesh_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'wmgm_mask')
elif "IsoSurface_brain_pipe" in params.keys():

IsoSurface_brain_pipe = create_IsoSurface_brain_pipe(
params=parse_key(params["brain_segment_pipe"],
"IsoSurface_brain_pipe"))

if pad:
if "native_to_stereo_pipe" in params.keys():

seg_pipe.connect(apply_stereo_seg_mask, "out_file",
IsoSurface_brain_pipe,
'inputnode.segmented_file')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_stl",
outputnode, 'stereo_wmgm_stl')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'stereo_wmgm_mask')

elif space == "native":
seg_pipe.connect(pad_seg_mask, "out_file",
IsoSurface_brain_pipe,
'inputnode.segmented_file')
else:
seg_pipe.connect(brain_segment_pipe, "outputnode.segmented_file",
IsoSurface_brain_pipe, 'inputnode.segmented_file')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_stl",
outputnode, 'wmgm_stl')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'wmgm_mask')

elif 'nii_to_mesh_pipe' in params.keys():
# kept for compatibility but nii2mesh is prefered...
Expand Down Expand Up @@ -3811,4 +3843,37 @@ def create_full_T1_ants_subpipes(params_template, params_template_aladin,
seg_pipe.connect(nii2mesh_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'wmgm_mask')

elif "IsoSurface_brain_pipe" in params["brain_segment_pipe"]:

IsoSurface_brain_pipe = create_IsoSurface_brain_pipe(
params=parse_key(params["brain_segment_pipe"],
"IsoSurface_brain_pipe"))

if pad:
if "native_to_stereo_pipe" in params.keys():

seg_pipe.connect(apply_stereo_seg_mask, "out_file",
IsoSurface_brain_pipe,
'inputnode.segmented_file')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_stl",
outputnode, 'stereo_wmgm_stl')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'stereo_wmgm_mask')

elif space == "native":
seg_pipe.connect(pad_seg_mask, "out_file",
IsoSurface_brain_pipe,
'inputnode.segmented_file')
else:
seg_pipe.connect(brain_segment_pipe, "outputnode.segmented_file",
IsoSurface_brain_pipe, 'inputnode.segmented_file')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_stl",
outputnode, 'wmgm_stl')

seg_pipe.connect(IsoSurface_brain_pipe, "outputnode.wmgm_nii",
outputnode, 'wmgm_mask')

return seg_pipe
115 changes: 44 additions & 71 deletions macapype/pipelines/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import nipype.interfaces.spm as spm

from ..nodes.segment import (AtroposN4, BinaryFillHoles, merge_masks,
from ..nodes.segment import (AtroposN4, merge_masks,
merge_imgs, split_indexed_mask, copy_header,
compute_5tt, fill_list_vol)

Expand Down Expand Up @@ -724,31 +724,12 @@ def create_native_old_segment_pipe(params_template, params={},
assert set_spm(), \
"Error, SPM was not found, cannot run SPM old segment pipeline"

unzip = pe.Node(
interface=niu.Function(input_names=['zipped_file'],
output_names=["unzipped_file"],
function=gunzip),
name="unzip")

seg_pipe.connect(inputnode, 'T1', unzip, 'zipped_file')

# Segment in to 6 tissues
segment = NodeParams(spm.Segment(),
params=parse_key(params, "segment"),
name="old_segment")

segment.inputs.tissue_prob_maps = [params_template["template_gm"],
params_template["template_wm"],
params_template["template_csf"]]

seg_pipe.connect(unzip, 'unzipped_file', segment, 'data')

# gm
register_gm_to_nat = pe.Node(fsl.ApplyXFM(), name="register_gm_to_nat")
register_gm_to_nat.inputs.output_type = "NIFTI_GZ" # for SPM segment
register_gm_to_nat.inputs.output_type = "NIFTI" # for SPM segment
register_gm_to_nat.inputs.interp = "nearestneighbour"

seg_pipe.connect(segment, 'native_gm_image',
register_gm_to_nat, 'in_file')
register_gm_to_nat.inputs.in_file = params_template["template_gm"]

seg_pipe.connect(inputnode, 'native_T1',
register_gm_to_nat, 'reference')
Expand All @@ -758,10 +739,10 @@ def create_native_old_segment_pipe(params_template, params={},

# wm
register_wm_to_nat = pe.Node(fsl.ApplyXFM(), name="register_wm_to_nat")
register_wm_to_nat.inputs.output_type = "NIFTI_GZ" # for SPM segment
register_wm_to_nat.inputs.output_type = "NIFTI" # for SPM segment
register_wm_to_nat.inputs.interp = "nearestneighbour"

seg_pipe.connect(segment, 'native_wm_image',
register_wm_to_nat, 'in_file')
register_wm_to_nat.inputs.in_file = params_template["template_wm"]

seg_pipe.connect(inputnode, 'native_T1',
register_wm_to_nat, 'reference')
Expand All @@ -771,23 +752,51 @@ def create_native_old_segment_pipe(params_template, params={},

# csf
register_csf_to_nat = pe.Node(fsl.ApplyXFM(), name="register_csf_to_nat")
register_csf_to_nat.inputs.output_type = "NIFTI_GZ" # for SPM segment
register_csf_to_nat.inputs.output_type = "NIFTI" # for SPM segment
register_csf_to_nat.inputs.interp = "nearestneighbour"

seg_pipe.connect(segment, 'native_csf_image',
register_csf_to_nat, 'in_file')
register_csf_to_nat.inputs.in_file = params_template["template_csf"]

seg_pipe.connect(inputnode, 'native_T1',
register_csf_to_nat, 'reference')

seg_pipe.connect(inputnode, 'inv_transfo_file',
register_csf_to_nat, "in_matrix_file")
# unzip T1
unzip = pe.Node(
interface=niu.Function(input_names=['zipped_file'],
output_names=["unzipped_file"],
function=gunzip),
name="unzip")

seg_pipe.connect(inputnode, 'T1', unzip, 'zipped_file')

# merge_tissue_files
merge_tissue_files = pe.Node(
interface=niu.Merge(3),
name="merge_tissue_files")

seg_pipe.connect(register_gm_to_nat, "out_file", merge_tissue_files, 'in1')
seg_pipe.connect(register_wm_to_nat, "out_file", merge_tissue_files, 'in2')
seg_pipe.connect(register_csf_to_nat, "out_file",
merge_tissue_files, 'in3')

# Segment in to 6 tissues
segment = NodeParams(spm.Segment(),
params=parse_key(params, "segment"),
name="old_segment")

seg_pipe.connect(merge_tissue_files, "out",
segment, "tissue_prob_maps")

seg_pipe.connect(unzip, 'unzipped_file', segment, 'data')

# threshold_gm
threshold_gm = NodeParams(fsl.Threshold(),
params=parse_key(params, "threshold_gm"),
name="threshold_gm")

seg_pipe.connect(register_gm_to_nat, 'out_file', threshold_gm, 'in_file')
seg_pipe.connect(segment, 'native_gm_image', threshold_gm, 'in_file')

seg_pipe.connect(
inputnode, ('indiv_params', parse_key, "threshold_gm"),
Expand All @@ -798,7 +807,7 @@ def create_native_old_segment_pipe(params_template, params={},
params=parse_key(params, "threshold_wm"),
name="threshold_wm")

seg_pipe.connect(register_wm_to_nat, 'out_file', threshold_wm, 'in_file')
seg_pipe.connect(segment, 'native_wm_image', threshold_wm, 'in_file')

seg_pipe.connect(
inputnode, ('indiv_params', parse_key, "threshold_wm"),
Expand All @@ -809,7 +818,7 @@ def create_native_old_segment_pipe(params_template, params={},
params=parse_key(params, "threshold_csf"),
name="threshold_csf")

seg_pipe.connect(register_csf_to_nat, 'out_file', threshold_csf, 'in_file')
seg_pipe.connect(segment, 'native_csf_image', threshold_csf, 'in_file')

seg_pipe.connect(
inputnode, ('indiv_params', parse_key, "threshold_csf"),
Expand All @@ -826,9 +835,9 @@ def create_native_old_segment_pipe(params_template, params={},
seg_pipe.connect(threshold_wm, 'out_file', outputnode, 'threshold_wm')
seg_pipe.connect(threshold_csf, 'out_file', outputnode, 'threshold_csf')

seg_pipe.connect(register_gm_to_nat, 'out_file', outputnode, 'prob_gm')
seg_pipe.connect(register_wm_to_nat, 'out_file', outputnode, 'prob_wm')
seg_pipe.connect(register_csf_to_nat, 'out_file', outputnode, 'prob_csf')
seg_pipe.connect(segment, 'native_gm_image', outputnode, 'prob_gm')
seg_pipe.connect(segment, 'native_wm_image', outputnode, 'prob_wm')
seg_pipe.connect(segment, 'native_csf_image', outputnode, 'prob_csf')

return seg_pipe

Expand Down Expand Up @@ -892,42 +901,6 @@ def create_mask_from_seg_pipe(params={}, name="mask_from_seg_pipe"):
seg_pipe.connect(inputnode, 'mask_wm',
bin_wm, 'in_file')

# Compute union of the 3 tissues
# Done with 2 fslmaths as it seems to hard to do it
wmgm_union = pe.Node(fsl.BinaryMaths(), name="wmgm_union")
wmgm_union.inputs.operation = "add"
seg_pipe.connect(bin_gm, 'out_file', wmgm_union, 'in_file')
seg_pipe.connect(bin_wm, 'out_file', wmgm_union, 'operand_file')

tissues_union = pe.Node(fsl.BinaryMaths(), name="tissues_union")
tissues_union.inputs.operation = "add"
seg_pipe.connect(wmgm_union, 'out_file', tissues_union, 'in_file')
seg_pipe.connect(bin_csf, 'out_file',
tissues_union, 'operand_file')

# Opening (dilating) mask
dilate_mask = NodeParams(fsl.DilateImage(),
params=parse_key(params, "dilate_mask"),
name="dilate_mask")

dilate_mask.inputs.operation = "mean" # Arbitrary operation
seg_pipe.connect(tissues_union, 'out_file', dilate_mask, 'in_file')

# fill holes of dilate_mask
fill_holes_dil = pe.Node(BinaryFillHoles(), name="fill_holes_dil")
seg_pipe.connect(dilate_mask, 'out_file', fill_holes_dil, 'in_file')

# Eroding mask
erode_mask = NodeParams(fsl.ErodeImage(),
params=parse_key(params, "erode_mask"),
name="erode_mask")

seg_pipe.connect(tissues_union, 'out_file', erode_mask, 'in_file')

# fill holes of erode_mask
fill_holes = pe.Node(BinaryFillHoles(), name="fill_holes")
seg_pipe.connect(erode_mask, 'out_file', fill_holes, 'in_file')

# merge to index
merge_indexed_mask = NodeParams(
interface=niu.Function(input_names=["mask_csf_file", "mask_wm_file",
Expand Down
55 changes: 54 additions & 1 deletion macapype/pipelines/surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import macapype.nodes.register as reg

from macapype.nodes.surface import (Meshify, split_LR_mask,
wrap_nii2mesh, merge_tissues)
wrap_nii2mesh,
wrap_afni_IsoSurface, merge_tissues)

from macapype.utils.utils_nodes import parse_key, NodeParams

Expand Down Expand Up @@ -683,3 +684,55 @@ def create_nii2mesh_brain_pipe(params={},
nii2mesh_brain_pipe.connect(wmgm2mesh, 'stl_file', outputnode, "wmgm_stl")

return nii2mesh_brain_pipe


def create_IsoSurface_brain_pipe(params={},
name="IsoSurface_brain_pipe"):

# creating pipeline
IsoSurface_brain_pipe = pe.Workflow(name=name)

# creating inputnode
inputnode = pe.Node(
niu.IdentityInterface(
fields=["segmented_file"]),
name='inputnode')

# merge_brain_tissues
merge_brain_tissues = NodeParams(
interface=niu.Function(input_names=["dseg_file", "keep_indexes"],
output_names=["mask_file"],
function=merge_tissues),
params=parse_key(params, "merge_brain_tissues"),
name="keep_GCC_brain")

IsoSurface_brain_pipe.connect(inputnode, 'segmented_file',
merge_brain_tissues, 'dseg_file')

# bin mask
bin_mask = pe.Node(interface=fsl.UnaryMaths(), name="bin_mask")
bin_mask.inputs.operation = "bin"

IsoSurface_brain_pipe.connect(merge_brain_tissues,
'mask_file', bin_mask, 'in_file')

# wmgm2mesh
wmgm2mesh = pe.Node(
interface=niu.Function(input_names=["nii_file"],
output_names=["stl_file"],
function=wrap_afni_IsoSurface),
name="wmgm2mesh")

IsoSurface_brain_pipe.connect(bin_mask, 'out_file', wmgm2mesh, "nii_file")

# outputnode
outputnode = pe.Node(
niu.IdentityInterface(
fields=["wmgm_stl", "wmgm_nii"]),
name='outputnode')

IsoSurface_brain_pipe.connect(bin_mask, 'out_file', outputnode, "wmgm_nii")
IsoSurface_brain_pipe.connect(wmgm2mesh, 'stl_file',
outputnode, "wmgm_stl")

return IsoSurface_brain_pipe
2 changes: 1 addition & 1 deletion workflows/params_segment_macaque_ants.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"export_5tt_pipe":
{
},
"nii2mesh_brain_pipe":
"IsoSurface_brain_pipe":
{
"merge_brain_tissues":
{
Expand Down
Loading