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
4 changes: 4 additions & 0 deletions .circleci/bcp_anat_outputs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T1w_to-fsnative_mode-image_xfm.t
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-T1w_mode-image_xfm.h5
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-fsnative_to-T1w_mode-image_xfm.txt
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_pial.surf.gii
Expand All @@ -31,6 +33,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_sulc.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_thickness.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_white.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_pial.surf.gii
Expand Down
4 changes: 4 additions & 0 deletions .circleci/bcp_anat_t2only_outputs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-MNIInfant+1_mode-image_xf
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-fsnative_mode-image_xfm.txt
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-fsnative_to-T2w_mode-image_xfm.txt
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_pial.surf.gii
Expand All @@ -32,6 +34,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_sulc.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_thickness.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_white.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_pial.surf.gii
Expand Down
4 changes: 4 additions & 0 deletions .circleci/bcp_full_outputs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T1w_to-fsnative_mode-image_xfm.t
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-T1w_mode-image_xfm.h5
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-fsnative_to-T1w_mode-image_xfm.txt
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_pial.surf.gii
Expand All @@ -31,6 +33,8 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_sulc.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_thickness.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_white.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_curv.shape.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_desc-cortex_mask.label.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_inflated.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_pial.surf.gii
Expand Down
8 changes: 8 additions & 0 deletions nibabies/data/io_spec_anat.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@
"desc": "msmsulc",
"suffix": "sphere",
"extension": ".surf.gii"
},
"cortex_mask": {
"datatype": "anat",
"hemi": ["L", "R"],
"space": null,
"desc": "cortex",
"suffix": "mask",
"extension": ".label.gii"
}
},
"masks": {
Expand Down
8 changes: 3 additions & 5 deletions nibabies/workflows/anatomical/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def init_infant_anat_apply_wf(
'white',
'pial',
'midthickness',
'cortex_mask',
reg_sphere,
# template workflow inputs
'std_t1w',
Expand All @@ -75,7 +76,7 @@ def init_infant_anat_apply_wf(
)

outputnode = pe.Node(
niu.IdentityInterface(fields=['anat_aseg', 'anat_aparc', 'midthickness_fsLR', 'roi']),
niu.IdentityInterface(fields=['anat_aseg', 'anat_aparc', 'midthickness_fsLR']),
name='outputnode',
)

Expand Down Expand Up @@ -235,17 +236,14 @@ def init_infant_anat_apply_wf(
(reg_sphere, 'inputnode.sphere_reg_fsLR'),
]),
(inputnode, morph_grayords_wf, [
('cortex_mask', 'inputnode.roi'),
('midthickness', 'inputnode.midthickness'),
(reg_sphere, 'inputnode.sphere_reg_fsLR'),
]),
(hcp_morphometrics_wf, morph_grayords_wf, [
('outputnode.curv', 'inputnode.curv'),
('outputnode.sulc', 'inputnode.sulc'),
('outputnode.thickness', 'inputnode.thickness'),
('outputnode.roi', 'inputnode.roi'),
]),
(hcp_morphometrics_wf, outputnode, [
('outputnode.roi', 'roi'),
]),
(resample_surfaces_wf, morph_grayords_wf, [
('outputnode.midthickness_fsLR', 'inputnode.midthickness_fsLR'),
Expand Down
94 changes: 75 additions & 19 deletions nibabies/workflows/anatomical/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@
from niworkflows.utils.connections import pop_file
from smriprep.workflows.anatomical import (
_is_skull_stripped,
init_anat_ribbon_wf,
init_anat_template_wf,
)
from smriprep.workflows.fit.registration import init_register_template_wf
from smriprep.workflows.outputs import (
init_ds_dseg_wf,
init_ds_fs_registration_wf,
init_ds_mask_wf,
init_ds_surface_masks_wf,
init_ds_surface_metrics_wf,
init_ds_surfaces_wf,
init_ds_template_registration_wf,
init_ds_template_wf,
init_ds_tpms_wf,
)
from smriprep.workflows.surfaces import (
init_anat_ribbon_wf,
init_cortex_masks_wf,
init_fsLR_reg_wf,
init_gifti_morphometrics_wf,
init_gifti_surfaces_wf,
Expand Down Expand Up @@ -147,6 +149,7 @@ def init_infant_anat_fit_wf(
'sphere_reg',
'sphere_reg_fsLR',
'sphere_reg_msm',
'cortex_mask',
'anat_ribbon',
# Reverse transform; not computable from forward transform
'std2anat_xfm',
Expand Down Expand Up @@ -1273,13 +1276,13 @@ def init_infant_anat_fit_wf(
(fsnative_buffer, gifti_surfaces_wf, [
('fsnative2anat_xfm', 'inputnode.fsnative2anat_xfm'),
]),
(gifti_surfaces_wf, surfaces_buffer, [
(f'outputnode.{surf}', surf) for surf in surfs
]),
(sourcefile_buffer, ds_surfaces_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_surfaces_wf, ds_surfaces_wf, [
(f'outputnode.{surf}', f'inputnode.{surf}') for surf in surfs
]),
(ds_surfaces_wf, surfaces_buffer, [
(f'outputnode.{surf}', surf) for surf in surfs
]),
]) # fmt:skip
if spheres:
gifti_spheres_wf = init_gifti_surfaces_wf(
Expand All @@ -1297,13 +1300,13 @@ def init_infant_anat_fit_wf(
('outputnode.subjects_dir', 'inputnode.subjects_dir'),
# No transform for spheres, following HCP pipelines' lead
]),
(gifti_spheres_wf, surfaces_buffer, [
(f'outputnode.{sphere}', sphere) for sphere in spheres
]),
(sourcefile_buffer, ds_spheres_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_spheres_wf, ds_spheres_wf, [
(f'outputnode.{sphere}', f'inputnode.{sphere}') for sphere in spheres
]),
(ds_spheres_wf, surfaces_buffer, [
(f'outputnode.{sphere}', sphere) for sphere in spheres
]),
]) # fmt:skip
metrics = [metric for metric in needed_metrics if metric not in found_surfs]
if metrics:
Expand All @@ -1321,13 +1324,13 @@ def init_infant_anat_fit_wf(
('outputnode.subject_id', 'inputnode.subject_id'),
('outputnode.subjects_dir', 'inputnode.subjects_dir'),
]),
(gifti_morph_wf, surfaces_buffer, [
(f'outputnode.{metric}', metric) for metric in metrics
]),
(sourcefile_buffer, ds_morph_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_morph_wf, ds_morph_wf, [
(f'outputnode.{metric}', f'inputnode.{metric}') for metric in metrics
]),
(ds_morph_wf, surfaces_buffer, [
(f'outputnode.{metric}', metric) for metric in metrics
]),
]) # fmt:skip

if 'anat_ribbon' not in precomputed:
Expand Down Expand Up @@ -1413,6 +1416,32 @@ def init_infant_anat_fit_wf(
else:
LOGGER.info('ANAT Stage 9: Found pre-computed fsLR registration sphere')
fsLR_buffer.inputs.sphere_reg_fsLR = sorted(precomputed['sphere_reg_fsLR'])

# Stage 10: Cortical surface mask
if len(precomputed.get('cortex_mask', [])) < 2:
LOGGER.info('ANAT Stage 11: Creating cortical surface mask')

cortex_masks_wf = init_cortex_masks_wf()
ds_cortex_masks_wf = init_ds_surface_masks_wf(
output_dir=output_dir,
mask_type='cortex',
name='ds_cortex_masks_wf',
)

workflow.connect([
(surfaces_buffer, cortex_masks_wf, [
('midthickness', 'inputnode.midthickness'),
('thickness', 'inputnode.thickness'),
]),
(cortex_masks_wf, ds_cortex_masks_wf, [
('outputnode.cortex_masks', 'inputnode.mask_files'),
('outputnode.source_files', 'inputnode.source_files'),
]),
(ds_cortex_masks_wf, outputnode, [('outputnode.mask_files', 'cortex_mask')]),
]) # fmt:skip
else:
LOGGER.info('ANAT Stage 11: Found pre-computed cortical surface mask')
outputnode.inputs.cortex_mask = sorted(precomputed['cortex_mask'])
return workflow


Expand Down Expand Up @@ -1476,6 +1505,7 @@ def init_infant_single_anat_fit_wf(
'sphere_reg',
'sphere_reg_fsLR',
'sphere_reg_msm',
'cortex_mask',
'anat_ribbon',
# Reverse transform; not computable from forward transform
'std2anat_xfm',
Expand Down Expand Up @@ -2202,13 +2232,13 @@ def init_infant_single_anat_fit_wf(
(fsnative_buffer, gifti_surfaces_wf, [
('fsnative2anat_xfm', 'inputnode.fsnative2anat_xfm'),
]),
(gifti_surfaces_wf, surfaces_buffer, [
(f'outputnode.{surf}', surf) for surf in surfs
]),
(sourcefile_buffer, ds_surfaces_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_surfaces_wf, ds_surfaces_wf, [
(f'outputnode.{surf}', f'inputnode.{surf}') for surf in surfs
]),
(ds_surfaces_wf, surfaces_buffer, [
(f'outputnode.{surf}', surf) for surf in surfs
]),
]) # fmt:skip
if spheres:
gifti_spheres_wf = init_gifti_surfaces_wf(
Expand All @@ -2226,13 +2256,13 @@ def init_infant_single_anat_fit_wf(
('outputnode.subjects_dir', 'inputnode.subjects_dir'),
# No transform for spheres, following HCP pipelines' lead
]),
(gifti_spheres_wf, surfaces_buffer, [
(f'outputnode.{sphere}', sphere) for sphere in spheres
]),
(sourcefile_buffer, ds_spheres_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_spheres_wf, ds_spheres_wf, [
(f'outputnode.{sphere}', f'inputnode.{sphere}') for sphere in spheres
]),
(ds_spheres_wf, surfaces_buffer, [
(f'outputnode.{sphere}', sphere) for sphere in spheres
]),
]) # fmt:skip
metrics = [metric for metric in needed_metrics if metric not in found_surfs]
if metrics:
Expand All @@ -2250,13 +2280,13 @@ def init_infant_single_anat_fit_wf(
('outputnode.subject_id', 'inputnode.subject_id'),
('outputnode.subjects_dir', 'inputnode.subjects_dir'),
]),
(gifti_morph_wf, surfaces_buffer, [
(f'outputnode.{metric}', metric) for metric in metrics
]),
(sourcefile_buffer, ds_morph_wf, [('anat_source_files', 'inputnode.source_files')]),
(gifti_morph_wf, ds_morph_wf, [
(f'outputnode.{metric}', f'inputnode.{metric}') for metric in metrics
]),
(ds_morph_wf, surfaces_buffer, [
(f'outputnode.{metric}', metric) for metric in metrics
]),
]) # fmt:skip

if 'anat_ribbon' not in precomputed:
Expand Down Expand Up @@ -2342,4 +2372,30 @@ def init_infant_single_anat_fit_wf(
else:
LOGGER.info('ANAT Stage 9: Found pre-computed fsLR registration sphere')
fsLR_buffer.inputs.sphere_reg_fsLR = sorted(precomputed['sphere_reg_fsLR'])

# Stage 10: Cortical surface mask
if len(precomputed.get('cortex_mask', [])) < 2:
LOGGER.info('ANAT Stage 11: Creating cortical surface mask')

cortex_masks_wf = init_cortex_masks_wf()
ds_cortex_masks_wf = init_ds_surface_masks_wf(
output_dir=output_dir,
mask_type='cortex',
name='ds_cortex_masks_wf',
)

workflow.connect([
(surfaces_buffer, cortex_masks_wf, [
('midthickness', 'inputnode.midthickness'),
('thickness', 'inputnode.thickness'),
]),
(cortex_masks_wf, ds_cortex_masks_wf, [
('outputnode.cortex_masks', 'inputnode.mask_files'),
('outputnode.source_files', 'inputnode.source_files'),
]),
(ds_cortex_masks_wf, outputnode, [('outputnode.mask_files', 'cortex_mask')]),
]) # fmt:skip
else:
LOGGER.info('ANAT Stage 11: Found pre-computed cortical surface mask')
outputnode.inputs.cortex_mask = sorted(precomputed['cortex_mask'])
return workflow
5 changes: 4 additions & 1 deletion nibabies/workflows/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ def init_single_subject_wf(
('outputnode.white', 'inputnode.white'),
('outputnode.pial', 'inputnode.pial'),
('outputnode.midthickness', 'inputnode.midthickness'),
('outputnode.cortex_mask', 'inputnode.cortex_mask'),
(f'outputnode.{reg_sphere}', f'inputnode.{reg_sphere}'),
('outputnode.sulc', 'inputnode.sulc'),
('outputnode.subjects_dir', 'inputnode.subjects_dir'),
Expand Down Expand Up @@ -809,8 +810,10 @@ def init_single_subject_wf(

if config.workflow.cifti_output:
workflow.connect([
(anat_fit_wf, bold_wf, [
('outputnode.cortex_mask', 'inputnode.cortex_mask'),
]),
(anat_apply_wf, bold_wf, [
('outputnode.roi', 'inputnode.cortex_mask'),
('outputnode.midthickness_fsLR', 'inputnode.midthickness_fsLR'),
('outputnode.anat_aseg', 'inputnode.anat_aseg'),
]),
Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ dependencies = [
"nireports >= 23.2.0",
"nitime",
"nitransforms >= 24.1.1",
#"niworkflows >= 1.13.1",
"niworkflows @ git+https://github.com/nipreps/niworkflows.git@master",
"niworkflows >= 1.14.1",
"numpy >= 1.21.0",
"packaging",
"pandas < 3",
Expand All @@ -35,7 +34,7 @@ dependencies = [
"pybids >= 0.15.0",
"requests",
"sdcflows >= 2.13.0",
"smriprep >= 0.17.0",
"smriprep >= 0.19.1",
"tedana >= 23.0.2",
"templateflow >= 24.2.0",
"toml",
Expand Down