|
33 | 33 | hardcoded_reg, \ |
34 | 34 | one_d_to_mat, \ |
35 | 35 | run_c3d, \ |
36 | | - run_c4d |
| 36 | + run_c4d, \ |
| 37 | + prepend_space |
37 | 38 | from CPAC.utils.interfaces.fsl import Merge as fslMerge |
38 | 39 | from CPAC.utils.typing import LIST_OR_STR, TUPLE |
39 | 40 | from CPAC.utils.utils import check_prov_for_motion_tool, check_prov_for_regtool |
@@ -3512,121 +3513,94 @@ def apply_blip_to_timeseries_separately(wf, cfg, strat_pool, pipe_num, |
3512 | 3513 | return (wf, outputs) |
3513 | 3514 |
|
3514 | 3515 |
|
3515 | | -@nodeblock( |
3516 | | - name="transform_whole_head_T1w_to_T1template", |
3517 | | - config=["registration_workflows", "anatomical_registration"], |
3518 | | - switch=["run"], |
3519 | | - inputs=[ |
3520 | | - ( |
3521 | | - ["desc-head_T1w", "space-longitudinal_desc-reorient_T1w"], |
3522 | | - ["from-T1w_to-template_mode-image_xfm", |
3523 | | - "from-longitudinal_to-template_mode-image_xfm"], |
3524 | | - "space-template_desc-head_T1w", |
3525 | | - ), |
3526 | | - "T1w-template", |
3527 | | - ], |
3528 | | - outputs={"space-template_desc-head_T1w": {"Template": "T1w-template"}}, |
3529 | | -) |
3530 | | -def warp_wholeheadT1_to_template(wf, cfg, strat_pool, pipe_num, opt=None): |
3531 | | - xfm: list[str] = ["from-T1w_to-template_mode-image_xfm", |
3532 | | - "from-longitudinal_to-template_mode-image_xfm"] |
3533 | | - xfm_prov = strat_pool.get_cpac_provenance(xfm) |
3534 | | - reg_tool = check_prov_for_regtool(xfm_prov) |
3535 | | - |
3536 | | - num_cpus = cfg.pipeline_setup['system_config'][ |
3537 | | - 'max_cores_per_participant'] |
3538 | | - |
3539 | | - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] |
3540 | | - |
3541 | | - apply_xfm = apply_transform(f'warp_wholehead_T1w_to_T1template_{pipe_num}', |
3542 | | - reg_tool, time_series=False, num_cpus=num_cpus, |
3543 | | - num_ants_cores=num_ants_cores) |
3544 | | - |
3545 | | - if reg_tool == 'ants': |
3546 | | - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ |
3547 | | - 'functional_registration']['func_registration_to_template'][ |
3548 | | - 'ANTs_pipelines']['interpolation'] |
3549 | | - elif reg_tool == 'fsl': |
3550 | | - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ |
3551 | | - 'functional_registration']['func_registration_to_template'][ |
3552 | | - 'FNIRT_pipelines']['interpolation'] |
3553 | | - |
3554 | | - connect = strat_pool.get_data(["desc-head_T1w", |
3555 | | - "space-longitudinal_desc-reorient_T1w"]) |
3556 | | - node, out = connect |
3557 | | - wf.connect(node, out, apply_xfm, 'inputspec.input_image') |
3558 | | - |
3559 | | - node, out = strat_pool.get_data("T1w-template") |
3560 | | - wf.connect(node, out, apply_xfm, 'inputspec.reference') |
3561 | | - |
3562 | | - node, out = strat_pool.get_data("from-T1w_to-template_mode-image_xfm") |
3563 | | - wf.connect(node, out, apply_xfm, 'inputspec.transform') |
3564 | | - |
3565 | | - outputs = { |
3566 | | - 'space-template_desc-head_T1w': (apply_xfm, 'outputspec.output_image') |
3567 | | - } |
| 3516 | +def warp_to_template(warp_what: Literal["mask", "wholehead"], |
| 3517 | + space_from: Literal["longitudinal", "T1w"]) -> NodeBlockFunction: |
| 3518 | + """Get a NodeBlockFunction to transform a resource from ``space`` to template. |
3568 | 3519 |
|
3569 | | - return (wf, outputs) |
3570 | | - |
3571 | | -def warp_mask_to_template(space: Literal["longitudinal", "T1w"]) -> NodeBlockFunction: |
3572 | | - """Get a NodeBlockFunction to transform a mask from ``space`` to template.""" |
3573 | | - @nodeblock( |
3574 | | - name=f"transform_{space}-mask_to_T1-template", |
3575 | | - switch=[ |
| 3520 | + The resource being warped needs to be the first list or string in the tuple |
| 3521 | + in the first position of the decorator's "inputs". |
| 3522 | + """ |
| 3523 | + _decorators = {"mask": { |
| 3524 | + "name": f"transform_{space_from}-mask_to_T1-template", |
| 3525 | + "switch": [ |
3576 | 3526 | ["registration_workflows", "anatomical_registration", "run"], |
3577 | 3527 | ["anatomical_preproc", "run"], |
3578 | 3528 | ["anatomical_preproc", "brain_extraction", "run"], |
3579 | 3529 | ], |
3580 | | - inputs=[ |
3581 | | - (f"space-{space}_desc-brain_mask", |
3582 | | - f"from-{space}_to-template_mode-image_xfm"), |
| 3530 | + "inputs": [ |
| 3531 | + (f"space-{space_from}_desc-brain_mask", |
| 3532 | + f"from-{space_from}_to-template_mode-image_xfm"), |
3583 | 3533 | "T1w-template", |
3584 | 3534 | ], |
3585 | | - outputs={"space-template_desc-brain_mask": {"Template": "T1w-template"}}, |
3586 | | - ) |
3587 | | - def warp_mask_to_template_fxn(wf, cfg, strat_pool, pipe_num, opt=None): |
3588 | | - """Transform a mask to template space.""" |
| 3535 | + "outputs": {"space-template_desc-brain_mask": {"Template": "T1w-template"}}, |
| 3536 | + }, "wholehead": { |
| 3537 | + "name": f"transform_wholehead_{space_from}_to_T1template", |
| 3538 | + "config": ["registration_workflows", "anatomical_registration"], |
| 3539 | + "switch": ["run"], |
| 3540 | + "inputs": [ |
| 3541 | + ( |
| 3542 | + ["desc-head_T1w", "desc-reorient_T1w"], |
| 3543 | + [f"from-{space_from}_to-template_mode-image_xfm", |
| 3544 | + f"from-{space_from}_to-template_mode-image_xfm"], |
| 3545 | + "space-template_desc-head_T1w", |
| 3546 | + ), |
| 3547 | + "T1w-template", |
| 3548 | + ], |
| 3549 | + "outputs": {"space-template_desc-head_T1w": {"Template": "T1w-template"}}, |
| 3550 | + }} |
| 3551 | + if space_from != "T1w": |
| 3552 | + _decorators[warp_what]["inputs"][0] = tuple((prepend_space( |
| 3553 | + _decorators[warp_what]["inputs"][0][0], space_from), |
| 3554 | + *_decorators[warp_what]["inputs"][0][1:] |
| 3555 | + )) |
| 3556 | + |
| 3557 | + @nodeblock(**_decorators[warp_what]) |
| 3558 | + def warp_to_template_fxn(wf, cfg, strat_pool, pipe_num, opt=None): |
| 3559 | + """Transform a resource to template space.""" |
3589 | 3560 |
|
3590 | 3561 | xfm_prov = strat_pool.get_cpac_provenance( |
3591 | | - f'from-{space}_to-template_mode-image_xfm') |
| 3562 | + f'from-{space_from}_to-template_mode-image_xfm') |
3592 | 3563 | reg_tool = check_prov_for_regtool(xfm_prov) |
3593 | 3564 |
|
3594 | 3565 | num_cpus = cfg.pipeline_setup['system_config'][ |
3595 | 3566 | 'max_cores_per_participant'] |
3596 | 3567 |
|
3597 | 3568 | num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] |
3598 | 3569 |
|
3599 | | - apply_xfm = apply_transform(f'warp_T1mask_to_T1template_{pipe_num}', |
3600 | | - reg_tool, time_series=False, num_cpus=num_cpus, |
3601 | | - num_ants_cores=num_ants_cores) |
| 3570 | + apply_xfm = apply_transform( |
| 3571 | + f'warp_{space_from}{warp_what}_to_T1template_{pipe_num}', |
| 3572 | + reg_tool, time_series=False, num_cpus=num_cpus, |
| 3573 | + num_ants_cores=num_ants_cores) |
3602 | 3574 |
|
3603 | | - apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" |
3604 | | - ''' |
3605 | | - if reg_tool == 'ants': |
3606 | | - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ |
3607 | | - 'functional_registration']['func_registration_to_template'][ |
3608 | | - 'ANTs_pipelines']['interpolation'] |
3609 | | - elif reg_tool == 'fsl': |
| 3575 | + if warp_what == "mask": |
| 3576 | + apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" |
| 3577 | + else: |
| 3578 | + tool = "ANTs" if reg_tool == 'ants' else 'FNIRT' if reg_tool == 'fsl' else None |
| 3579 | + if not tool: |
| 3580 | + msg = f"Warp {warp_what} to template not implemented for {reg_tool}." |
| 3581 | + raise NotImplementedError(msg) |
3610 | 3582 | apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ |
3611 | 3583 | 'functional_registration']['func_registration_to_template'][ |
3612 | | - 'FNIRT_pipelines']['interpolation'] |
3613 | | - ''' |
3614 | | - connect = strat_pool.get_data(f"space-{space}_desc-brain_mask") |
3615 | | - node, out = connect |
| 3584 | + f'{tool}_pipelines']['interpolation'] |
| 3585 | + |
| 3586 | + # the resource being warped needs to be inputs[0][0] for this |
| 3587 | + node, out = strat_pool.get_data(_decorators[warp_what]["inputs"][0][0]) |
3616 | 3588 | wf.connect(node, out, apply_xfm, 'inputspec.input_image') |
3617 | 3589 |
|
3618 | 3590 | node, out = strat_pool.get_data("T1w-template") |
3619 | 3591 | wf.connect(node, out, apply_xfm, 'inputspec.reference') |
3620 | 3592 |
|
3621 | | - node, out = strat_pool.get_data(f"from-{space}_to-template_mode-image_xfm") |
| 3593 | + node, out = strat_pool.get_data(f"from-{space_from}_to-template_mode-image_xfm") |
3622 | 3594 | wf.connect(node, out, apply_xfm, 'inputspec.transform') |
3623 | 3595 |
|
3624 | 3596 | outputs = { |
3625 | | - 'space-template_desc-brain_mask': (apply_xfm, 'outputspec.output_image') |
| 3597 | + # there's only one output, so that's what we give here |
| 3598 | + list(_decorators[warp_what]["outputs"].keys())[0]: ( |
| 3599 | + apply_xfm, 'outputspec.output_image') |
3626 | 3600 | } |
3627 | 3601 |
|
3628 | 3602 | return wf, outputs |
3629 | | - return warp_mask_to_template_fxn |
| 3603 | + return warp_to_template_fxn |
3630 | 3604 |
|
3631 | 3605 |
|
3632 | 3606 | @nodeblock( |
|
0 commit comments