Source code for cmind.pipeline.ants_register

#!/usr/bin/env python
"""
utility for calling antsRegistration
"""
from __future__ import division, print_function, absolute_import

import os
import warnings
from os.path import join as pjoin

from cmind.pipeline.ants_applywarp import ants_applywarp
from cmind.utils.utils import input2bool
from cmind.utils.file_utils import imexist
from cmind.utils.logging_utils import cmind_init_logging, log_cmd, cmind_func_info
from cmind.globals import cmind_ANTs_init_COM_string


[docs]def ants_register(fixed,moving,output_dir, output_root,ANTS_path=None,operation_type="both",initial_COM_alignment=True,use_Bspline_SyN=False,registration_mask_fixed=None,registration_mask_moving=None,affine_only=False,rigid_affine=False,concat_transforms=True,dim=3,interp_type='Linear',nopng=False,precision_case='lenient', initial_transform_list=None, verbose=False, logger=None): """utility to call antsRegistration Parameters ---------- fixed : str image filename for the fixed image (registration target) moving : str image filename for the moving image output_dir : str path to store the output output_root : str filenames of the transforms will be ${output_dir}/${output_root}0GenericAffine.mat, etc ANTS_path : str path to the ants binaries operation_type : {"compute","apply","both"}, optional compute = compute registration only, apply = apply existing registration only, both = compute & apply registration initial_COM_alignment : bool, optional align center of mass of the volumes prior to other registration stages? use_Bspline_SyN : bool, optional use B-Spline variant of SyN instead registration_mask_fixed : str, optional filename of binary weight mask to be applied to fixed image during registration registration_mask_moving : str, optional filename of binary weight mask to be applied to moving image during registration affine_only : bool, optional If true, only do a linear, affine transformation rigid_affine : bool, optional If true, do only a rigid registration concat_transforms : bool, optional concatenate transforms dim : {2, 3}, optional number of image dimensions interp_type : str, optional interpolation type nopng : bool, optional if False, generate overlay images summarizing the registration precision_case : {'defacer','lenient','ants_default','strict'}, optional choose from preset precision levels for the registrations initial_transform_list : list of str, optional initialize the registrtion using this list of transforms verbose : bool, optional print additional output (to terminal and log) logger : logging.Logger or str, optional logging.Logger object (or string of a filename to log to) Returns ------- warp_file : str file containing the calculated warp aff_file : str file containing the calculated affine transform output_warped : str file containing the warped image Notes ----- Possible `interp_type` strings are: - HammingWindowedSinc - NearestNeighbor - BSpline[<order=3>] - MultiLabel[<sigma=imageSpacing>,<alpha=4.0>] - Gaussian[<sigma=imageSpacing>,<alpha=1.0>] - CosineWindowedSinc - WelchWindowedSinc - HammingWindowedSinc - LanczosWindowedSinc - "" """ #/media/Data1/BRAINSTools/bin/antsRegistration -d 3 -u 1 -w [0.01 0.99] -z 1 -r["/media/Data2/CMIND/Matlab_Output/cmind_templates_new/RIGID/48to216_template_brain_2mm.nii.gz","/media/Data1/CMIND_Other/Matlab_Output/02F021/P/T1_proc_new/T1W_Structural_N4_brain.nii.gz",1] -t Rigid[0.1] -m MI["/media/Data2/CMIND/Matlab_Output/cmind_templates_new/RIGID/48to216_template_brain_2mm.nii.gz","/media/Data1/CMIND_Other/Matlab_Output/02F021/P/T1_proc_new/T1W_Structural_N4_brain.nii.gz",,32,Regular,0.1] -c [1000x1000x1000x1000,5e-8,10] -f 8x4x2x1 -s 4x2x1x0 -t Affine[0.1] -m MI["/media/Data2/CMIND/Matlab_Output/cmind_templates_new/RIGID/48to216_template_brain_2mm.nii.gz","/media/Data1/CMIND_Other/Matlab_Output/02F021/P/T1_proc_new/T1W_Structural_N4_brain.nii.gz",,32,Regular,0.1] -c [1000x1000x1000x1000,5e-8,10] -f 8x4x2x1 -s 4x2x1x0 -t SyN[0.15,3,0.0] -m CC["/media/Data2/CMIND/Matlab_Output/cmind_templates_new/RIGID/48to216_template_brain_2mm.nii.gz","/media/Data1/CMIND_Other/Matlab_Output/02F021/P/T1_proc_new/T1W_Structural_N4_brain.nii.gz",,4] -c [100x70x20,1e-8,10] -f 4x2x1 -s 2x1x0 -o "/media/Data1/CMIND_Other/Matlab_Output/02F021/P/T1_proc_new/temp/T1_to_StudyTemplate_ANTS_SyN_" -v 2 initial_COM_alignment, use_Bspline_SyN, affine_only, rigid_affine, concat_transforms, nopng, verbose = input2bool([initial_COM_alignment, use_Bspline_SyN, affine_only, rigid_affine, concat_transforms, nopng, verbose]) if verbose: cmind_func_info(logger=logger) module_logger=cmind_init_logging(verbose=verbose, logger=logger) module_logger.info("Starting ants_register") if not os.path.exists(output_dir): os.makedirs(output_dir) (fixed_exists, fixed_full)=imexist(fixed)[0:2]; if fixed_exists: fixed=fixed_full else: raise IOError("Fixed image, %s, doesn't exist!" % (fixed)) (moving_exists, moving_full)=imexist(moving)[0:2]; if moving_exists: moving=moving_full else: raise IOError("Moving image, %s, doesn't exist!" % (moving)) if concat_transforms: concat_transforms=1 else: concat_transforms=0 output_root=os.path.basename(output_root) #strip directory from output_root if affine_only: warp_file="" else: warp_file=pjoin(output_dir,output_root + '1Warp.nii.gz') # if(rigid_affine) # aff_file=pjoin(output_dir,output_root + '0RigidAffine.mat') # else aff_file=pjoin(output_dir,output_root + '0GenericAffine.mat'); # end operation_type=operation_type.lower() if (operation_type=="compute") or (operation_type=="both"): if initial_transform_list is None: #TODO: test/enable stage 0: initial center of mass alignment if initial_COM_alignment: #stage1_init=' --initial-moving-transform ["' + fixed + '","' + moving + '",useCenterOfMass] ' stage1_init=' --initial-moving-transform ["{}","{}",{}] '.format(fixed, moving, cmind_ANTs_init_COM_string) #0 = center of mass else: stage1_init='' else: #TODO: currently untested stage1_init=' --initial-moving-transform ' for item in initial_transform_list: stage1_init += ' ' + item stage1_init+=' ' #optionally mask the regions to be considered during registration if registration_mask_fixed: registration_mask_moving=None if registration_mask_moving: mask_str='--masks ["%s","%s"]' % (registration_mask_fixed,registration_mask_moving) else: mask_str='--masks ["%s"]' % (registration_mask_fixed) else: mask_str='' if use_Bspline_SyN: SplineDistance=26 syn_transform="BSplineSyN[0.1,%d,0,3]" % SplineDistance else: syn_transform="SyN[0.1,3,0]" #ants_defaults are based on values in antsRegistrationSyN.sh if precision_case.lower()=='lenient': stage1 = '-t Rigid[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x500x250x100,1e-6,10] -f 8x4x2x1 -s 4x2x1x0 ' + stage1_init; stage2 = '-t Affine[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x500x250x100,1e-6,10] -f 8x4x2x1 -s 4x2x1x0 '; stage3 = '-t '+syn_transform+' -m CC["' + fixed + '","' + moving + '",1,4] -c [100x70x50x20,1e-6,10] -f 6x4x2x1 -s 3x2x1x0 '; elif precision_case.lower()=='defacer': stage1 = '-t Rigid[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x500x250,1e-5,10] -f 8x4x2 -s 4x2x1 ' + stage1_init; stage2 = '-t Affine[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x500x250,1e-5,10] -f 8x4x2 -s 4x2x1 '; stage3 = '-t '+syn_transform+' -m CC["' + fixed + '","' + moving + '",1,4] -c [100x70x50,1e-5,10] -f 6x4x2 -s 3x2x1 '; elif precision_case.lower()=='ants_defaults': stage1 = '-t Rigid[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.1] -c [1000x500x250x100,1e-6,10] -f 8x4x2x1 -s 4x2x1x0 ' + stage1_init; stage2 = '-t Affine[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.1] -c [1000x500x250x100,1e-6,10] -f 8x4x2x1 -s 4x2x1x0 '; stage3 = '-t '+syn_transform+' -m CC["' + fixed + '","' + moving + '",1,4] -c [100x70x50x20,1e-6,10] -f 6x4x2x1 -s 3x2x1x0 '; elif precision_case.lower()=='strict': stage1 = '-t Rigid[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x1000x1000x1000,1e-9,10] -f 6x4x2x1 -s x2x1x0 ' + stage1_init; stage2 = '-t Affine[0.1] -m MI["' + fixed + '","' + moving + '",1,32,Regular,0.25] -c [1000x1000x1000x1000,1e-9,10] -f 6x4x2x1 -s 3x2x1x0 '; stage3 = '-t '+syn_transform+' -m CC["' + fixed + '","' + moving + '",1,4] -c [200x140x100x40,1e-9,10] -f 6x4x2x1 -s 3x2x1x0 '; else: ValueError("unrecognized precision_case option: {}".format(precision_case)) if affine_only: if rigid_affine: stage_str = stage1 backup_case = None else: stage_str = stage1 + stage2 backup_case = stage2 else: stage_str = stage1 + stage2 + stage3 backup_case = stage3 movie_opts=""; #movie_opts='--write-interval-volumes 5' %Doesn't seem to work?? if not ANTS_path: from cmind.globals import cmind_ANTs_dir as ANTS_path antsRegistration_cmd=pjoin(ANTS_path,'antsRegistration') if not interp_type: interp_type='Linear' #removed -r["%s","%s",1] . No longer used because stage1_init is specified above instead reg_command = '%s -d %d -u 1 -w [0.01, 0.99] -z %d %s %s %s --interpolation %s -o "%s" ' % (antsRegistration_cmd,dim,concat_transforms, movie_opts, stage_str, mask_str, interp_type, pjoin(output_dir,output_root)) try: #print "reg_command: " + reg_command log_cmd(reg_command, verbose=verbose, logger=logger) except: #on very rare occasion, RIGID or AFFINE stages fail, retry without them in this case print(" Failed to run: {}".format(reg_command)) if backup_case: print("warning: antsRegistration Failed! Trying backup case without initial rigid and affine stages") #removed -r["%s","%s",1] . No longer used because stage1_init is specified above instead reg_command = '%s -d %d -u 1 -w [0.01, 0.99] -z %d %s %s -o "%s" ' % (antsRegistration_cmd,dim,concat_transforms, movie_opts, backup_case,pjoin(output_dir,output_root)) log_cmd(reg_command, verbose=verbose, logger=logger) else: raise Exception("antsRegistration Failed!" ) if (operation_type=="apply") or (operation_type=="both"): try: transform_list=[] if affine_only: output_warped=pjoin(output_dir,output_root + 'AffineDeformed.nii.gz') transform_list.append(aff_file); #TODO else: transform_list.append(aff_file); transform_list.append(warp_file); output_warped=pjoin(output_dir,output_root + 'Deformed.nii.gz'); ants_applywarp(transform_list,fixed,moving,output_warped,ANTS_path=ANTS_path,dim=dim,interp_type=interp_type,nopng=nopng) except: warnings.warn('Failed to apply warp within {}'.format(__file__)) return (warp_file, aff_file, output_warped)