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
14 changes: 14 additions & 0 deletions .circleci/bcp_anat_t2only_outputs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ sub-01/ses-1mo
sub-01/ses-1mo/anat
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_desc-preproc_T2w.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_desc-preproc_T2w.nii.gz
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-MNI152NLin6Asym_to-T2w_mode-image_xfm.h5
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-MNIInfant+1_to-T2w_mode-image_xfm.h5
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-MNI152NLin6Asym_mode-image_xfm.h5
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_from-T2w_to-MNIInfant+1_mode-image_xfm.h5
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_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
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_space-fsLR_den-32k_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_space-fsLR_den-32k_pial.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_space-fsLR_den-32k_white.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_space-fsLR_desc-reg_sphere.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_space-fsaverage_desc-reg_sphere.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-L_sphere.surf.gii
Expand All @@ -30,6 +35,9 @@ 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_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
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_space-fsLR_den-32k_midthickness.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_space-fsLR_den-32k_pial.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_space-fsLR_den-32k_white.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_space-fsLR_desc-reg_sphere.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_space-fsaverage_desc-reg_sphere.surf.gii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_hemi-R_sphere.surf.gii
Expand All @@ -52,4 +60,10 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T2w_dseg.nii.gz
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T2w_label-CSF_probseg.nii.gz
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T2w_label-GM_probseg.nii.gz
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T2w_label-WM_probseg.nii.gz
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_curv.dscalar.nii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_curv.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_sulc.dscalar.nii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_sulc.json
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_thickness.dscalar.nii
sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-fsLR_den-91k_thickness.json
sub-01_ses-1mo.html
11 changes: 1 addition & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ _python_defaults: &python_defaults
password: $DOCKER_PAT
working_directory: /tmp/src/nibabies


_docker_auth: &docker_auth
name: Docker authentication
command: |
Expand Down Expand Up @@ -160,7 +159,6 @@ jobs:
- /tmp/docker
- /tmp/images


get_data:
!!merge <<: *python_defaults
working_directory: /home/circleci/data
Expand Down Expand Up @@ -279,7 +277,6 @@ jobs:
- store_artifacts:
path: /tmp/data/reports


test_bcp:
!!merge <<: *machine_defaults
environment:
Expand Down Expand Up @@ -412,7 +409,7 @@ jobs:
--nthreads 4 -vv --age-months 2 --sloppy \
--surface-recon-method infantfs \
--derivatives precomputed=/tmp/data/${DATASET}-t2only/derivatives/bibsnet \
--output-layout bids --anat-only
--output-layout bids --anat-only --cifti-output
- run:
name: Checking outputs of T2-only nibabies anat
command: |
Expand All @@ -427,7 +424,6 @@ jobs:
- store_artifacts:
path: /tmp/bcp/derivatives


deploy_docker_patches:
!!merge <<: *machine_defaults
working_directory: *src
Expand Down Expand Up @@ -464,7 +460,6 @@ jobs:
docker tag nipreps/nibabies:dev nipreps/nibabies:${CIRCLE_BRANCH#docker/}
docker push nipreps/nibabies:${CIRCLE_BRANCH#docker/}
deploy_docker:
!!merge <<: *machine_defaults
steps:
Expand Down Expand Up @@ -503,7 +498,6 @@ jobs:
fi
fi
test_deploy_pypi:
!!merge <<: *python_defaults
steps:
Expand Down Expand Up @@ -559,7 +553,6 @@ jobs:
- store_artifacts:
path: /tmp/src/nibabies/wrapper/dist


deploy_pypi:
!!merge <<: *python_defaults
steps:
Expand All @@ -584,14 +577,12 @@ jobs:
# upload wrapper
python -m twine upload wrapper/dist/nibabies*
deployable:
docker:
- image: busybox:latest
steps:
- run: echo Deploying!


workflows:
version: 2
build_test_deploy:
Expand Down
41 changes: 32 additions & 9 deletions nibabies/workflows/anatomical/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
from smriprep.workflows.surfaces import (
init_hcp_morphometrics_wf,
init_morph_grayords_wf,
init_resample_midthickness_wf,
init_resample_surfaces_wf,
init_surface_derivatives_wf,
)

from nibabies import config
from nibabies.workflows.anatomical.outputs import init_ds_seg_wf
from nibabies.workflows.anatomical.surfaces import init_resample_midthickness_dhcp_wf
from nibabies.workflows.anatomical.surfaces import init_resample_surfaces_dhcp_wf

if ty.TYPE_CHECKING:
from niworkflows.utils.spaces import SpatialReferences
Expand Down Expand Up @@ -57,6 +57,8 @@ def init_infant_anat_apply_wf(
'sulc',
'template',
'thickness',
'white',
'pial',
'midthickness',
reg_sphere,
# template workflow inputs
Expand Down Expand Up @@ -185,17 +187,28 @@ def init_infant_anat_apply_wf(
if cifti_output:
hcp_morphometrics_wf = init_hcp_morphometrics_wf(omp_nthreads=omp_nthreads)
if recon_method == 'mcribs':
resample_midthickness_wf = init_resample_midthickness_dhcp_wf(
grayord_density=cifti_output
resample_surfaces_wf = init_resample_surfaces_dhcp_wf(
surfaces=['white', 'pial', 'midthickness'],
grayord_density=cifti_output,
)
else:
resample_midthickness_wf = init_resample_midthickness_wf(
grayord_density=cifti_output
resample_surfaces_wf = init_resample_surfaces_wf(
surfaces=['white', 'pial', 'midthickness'], grayord_density=cifti_output
)
morph_grayords_wf = init_morph_grayords_wf(
grayord_density=cifti_output, omp_nthreads=omp_nthreads
)

ds_fsLR_surfaces_wf = init_ds_surfaces_wf(
output_dir=output_dir,
surfaces=['white', 'pial', 'midthickness'],
entities={
'space': 'dhcpAsym' if recon_method == 'mcribs' else 'fsLR',
'density': '32k' if cifti_output == '91k' else '59k',
},
name='ds_fsLR_surfaces_wf',
)

ds_grayord_metrics_wf = init_ds_grayord_metrics_wf(
bids_root=bids_root,
output_dir=output_dir,
Expand All @@ -213,7 +226,9 @@ def init_infant_anat_apply_wf(
(surface_derivatives_wf, hcp_morphometrics_wf, [
('outputnode.curv', 'inputnode.curv'),
]),
(inputnode, resample_midthickness_wf, [
(inputnode, resample_surfaces_wf, [
('white', 'inputnode.white'),
('pial', 'inputnode.pial'),
('midthickness', 'inputnode.midthickness'),
(reg_sphere, 'inputnode.sphere_reg_fsLR'),
]),
Expand All @@ -230,12 +245,20 @@ def init_infant_anat_apply_wf(
(hcp_morphometrics_wf, outputnode, [
('outputnode.roi', 'roi'),
]),
(resample_midthickness_wf, morph_grayords_wf, [
(resample_surfaces_wf, morph_grayords_wf, [
('outputnode.midthickness_fsLR', 'inputnode.midthickness_fsLR'),
]),
(resample_midthickness_wf, outputnode, [
(inputnode, ds_fsLR_surfaces_wf, [
('anat_valid_list', 'inputnode.source_files'),
]),
(resample_surfaces_wf, outputnode, [
('outputnode.midthickness_fsLR', 'midthickness_fsLR'),
]),
(resample_surfaces_wf, ds_fsLR_surfaces_wf, [
('outputnode.white_fsLR', 'inputnode.white'),
('outputnode.pial_fsLR', 'inputnode.pial'),
('outputnode.midthickness_fsLR', 'inputnode.midthickness'),
]),
(inputnode, ds_grayord_metrics_wf, [
('anat_valid_list', 'inputnode.source_files'),
]),
Expand Down
58 changes: 46 additions & 12 deletions nibabies/workflows/anatomical/surfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,10 @@ def init_make_midthickness_wf(
return workflow


def init_resample_midthickness_dhcp_wf(
def init_resample_surfaces_dhcp_wf(
surfaces: list[str],
grayord_density: ty.Literal['91k', '170k'],
name: str = 'resample_midthickness_wf',
name: str = 'resample_surfaces_dhcp_wf',
):
"""
Resample subject midthickness surface to specified density.
Expand All @@ -427,20 +428,20 @@ def init_resample_midthickness_dhcp_wf(
:graph2use: colored
:simple_form: yes
from nibabies.workflows.anatomical.surfaces import init_resample_midthickness_wf
wf = init_resample_midthickness_wf(grayord_density="91k")
from nibabies.workflows.anatomical.surfaces import init_resample_surfaces_dhcp_wf
wf = init_resample_surfaces_dhcp_wf(surfaces=['white', grayord_density='91k')
Parameters
----------
grayord_density : :obj:`str`
Either `91k` or `170k`, representing the total of vertices or *grayordinates*.
name : :obj:`str`
Unique name for the subworkflow (default: ``"resample_midthickness_wf"``)
Unique name for the subworkflow (default: ``"resample_surfaces_dhcp_wf``)
Inputs
------
midthickness
GIFTI surface mesh corresponding to the midthickness surface
``<surface>``
Left and right GIFTIs for each surface name passed to ``surfaces``
sphere_reg_fsLR
GIFTI surface mesh corresponding to the subject's fsLR registration sphere
Expand All @@ -454,11 +455,19 @@ def init_resample_midthickness_dhcp_wf(
fslr_density = '32k' if grayord_density == '91k' else '59k'

inputnode = pe.Node(
niu.IdentityInterface(fields=['midthickness', 'sphere_reg_fsLR']),
niu.IdentityInterface(fields=[*surfaces, 'sphere_reg_fsLR']),
name='inputnode',
)

outputnode = pe.Node(niu.IdentityInterface(fields=['midthickness_fsLR']), name='outputnode')
outputnode = pe.Node(
niu.IdentityInterface(fields=[f'{surf}_fsLR' for surf in surfaces]), name='outputnode'
)

surface_list = pe.Node(
niu.Merge(len(surfaces), ravel_inputs=True),
name='surface_list',
run_without_submitting=True,
)

resampler = pe.MapNode(
SurfaceResample(method='BARYCENTRIC'),
Expand All @@ -477,20 +486,45 @@ def init_resample_midthickness_dhcp_wf(
extension='.surf.gii',
)
)
# Order matters. Iterate over surfaces, then hemis to get L R L R L R
for _surf in surfaces
for hemi in ['L', 'R']
]

surface_groups = pe.Node(
niu.Split(splits=[2] * len(surfaces)),
name='surface_groups',
run_without_submitting=True,
)

workflow.connect([
(inputnode, surface_list, [
((surf, _sorted_by_basename), f'in{i}')
for i, surf in enumerate(surfaces, start=1)
]),
(inputnode, resampler, [
('midthickness', 'surface_in'),
('sphere_reg_fsLR', 'current_sphere'),
(('sphere_reg_fsLR', _repeat, len(surfaces)), 'current_sphere'),
]),
(surface_list, resampler, [('out', 'surface_in')]),
(resampler, surface_groups, [('surface_out', 'inlist')]),
(surface_groups, outputnode, [
(f'out{i}', f'{surf}_fsLR') for i, surf in enumerate(surfaces, start=1)
]),
(resampler, outputnode, [('surface_out', 'midthickness_fsLR')]),
]) # fmt:skip

return workflow


def _sorted_by_basename(inlist):
from os.path import basename

return sorted(inlist, key=lambda x: str(basename(x)))


def _repeat(seq: list, count: int) -> list:
return seq * count


def _parent(p):
from pathlib import Path

Expand Down
2 changes: 2 additions & 0 deletions nibabies/workflows/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ def init_single_subject_wf(
('outputnode.anat_dseg', 'inputnode.anat_dseg'),
('outputnode.anat_tpms', 'inputnode.anat_tpms'),
('outputnode.fsnative2anat_xfm', 'inputnode.fsnative2anat_xfm'),
('outputnode.white', 'inputnode.white'),
('outputnode.pial', 'inputnode.pial'),
('outputnode.midthickness', 'inputnode.midthickness'),
(f'outputnode.{reg_sphere}', f'inputnode.{reg_sphere}'),
('outputnode.sulc', 'inputnode.sulc'),
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ dependencies = [
"pybids >= 0.15.0",
"requests",
"sdcflows >= 2.10.0",
# "smriprep >= 0.16.1",
"smriprep @ git+https://github.com/nipreps/smriprep.git@dev-nibabies",
"smriprep >= 0.17.0",
"tedana >= 23.0.2",
"templateflow >= 24.2.0",
"toml",
Expand Down