Example #1
0
def _compose_transforms(transformDirectory, invert=False):
    """Strings together transofrm files in the correct order to apply a transform.
    """
    transforms = []
    if not invert:
        if '1Warp.nii.gz' in os.listdir(transformDirectory):
            SyN_file = os.path.join(transformDirectory, '1Warp.nii.gz')
            field = ants.image_read(SyN_file)
            transform = ants.transform_from_displacement_field(field)
            if transform is None:  # Adds compatibility with ANTsPy 2.0+
                transform = _transform_from_displacement_field(field)
            transforms.append(transform)
        if '0GenericAffine.mat' in os.listdir(transformDirectory):
            affine_file = os.path.join(transformDirectory,
                                       '0GenericAffine.mat')
            transforms.append(ants.read_transform(affine_file))
    else:
        if '0GenericAffine.mat' in os.listdir(transformDirectory):
            affine_file = os.path.join(transformDirectory,
                                       '0GenericAffine.mat')
            transforms.append(ants.read_transform(affine_file).invert())
        if '1InverseWarp.nii.gz' in os.listdir(transformDirectory):
            inv_file = os.path.join(transformDirectory, '1InverseWarp.nii.gz')
            field = ants.image_read(inv_file)
            transform = ants.transform_from_displacement_field(field)
            if transform is None:  # Adds compatibility with ANTsPy 2.0+
                transform = _transform_from_displacement_field(field)
            transforms.append(transform)
    return ants.compose_ants_transforms(transforms)
Example #2
0
    def test_read_write_transform(self):
        for tx in self.txs:
            filename = mktemp(suffix='.mat')
            ants.write_transform(tx, filename)
            tx2 = ants.read_transform(filename)

        # file doesnt exist
        with self.assertRaises(Exception):
            ants.read_transform('blah-blah.mat')
Example #3
0
def planewise_affine(fixed, moving, return_transforms=False):
    zshift = get_zshift(fixed, moving)

    fixed = to_numpy(fixed)
    moving = to_numpy(moving)

    size_z = fixed.shape[0]

    warped = np.zeros_like(fixed)
    transforms = [None]*size_z
    for z in prog_percent(list(range(max((0, -zshift)), min((size_z, -zshift + size_z))))):
        mov = ants.from_numpy(moving[z + zshift].swapaxes(0, 1))
        fix = ants.from_numpy(fixed[z].swapaxes(0, 1))
        res = ants.registration(mov, fix,
                                type_of_transform='Affine',
                                reg_iterations=[500, 500, 500],
                                grad_step=.1,
                                verbose=True)
        t = ants.read_transform(res['fwdtransforms'][0])
        transforms[z] = t
        trans = ants.apply_ants_transform_to_image(t, mov, fix)
        warped[z] = trans.numpy().swapaxes(0, 1)

    if return_transforms:
        return warped, (transforms, zshift)

    return warped
Example #4
0
def motion_correction(brain_master,
                      brain_slave,
                      motcorr_directory,
                      printlog,
                      meanbrain,
                      suffix=''):

    motCorr_brain_master = []
    motCorr_brain_slave = []
    durations = []
    transform_matrix = []

    for i in range(np.shape(brain_master)[-1]):
        #printlog('Aligning brain volume {}'.format(i))
        t0 = time()
        
        #First, align given master volume to master meanbrain
        with stderr_redirected(): # to prevent dumb itk gaussian error bullshit infinite printing
            # note meanbrain is already an ants object
            motCorr_vol = ants.registration(meanbrain, ants.from_numpy(brain_master[:,:,:,i]), type_of_transform='SyN')

        motCorr_brain_master.append(motCorr_vol['warpedmovout'].numpy())
        transformlist = motCorr_vol['fwdtransforms']

        #Use warp parameters on slave volume if provided
        if brain_slave:
            motCorr_brain_slave.append(ants.apply_transforms(meanbrain,ants.from_numpy(brain_slave[:,:,:,i]),transformlist).numpy())
        
        #Lets immediately grab the transform file because otherwise I think it is auto deleted due to "tmp" status...?
        #Indeed I think CentOS possibly perges /tmp pretty frequently
        #printlog('fwd_files: {}'.format(transformlist))
        for x in transformlist:
            if '.mat' in x:
                temp = ants.read_transform(x)
                transform_matrix.append(temp.parameters)
            os.remove(x)
            #printlog('Deleted fwd: {}'.format(x))

        # Delete invtransforms for /tmp directory size issue. note that .mat are shared, so only need to delete .nii.gz
        transformlist = motCorr_vol['invtransforms']
        #printlog('inv_files: {}'.format(transformlist))
        for x in transformlist:
            if '.mat' not in x:
                os.remove(x)
                #printlog('Deleted inv: {}'.format(x))

        print(F"[{i+1}]") #IMPORTANT FOR COMMUNICATION WITH DATAFLOW MAIN
        sys.stdout.flush()

    # Save motcorr brains
    save_motCorr_brain(motCorr_brain_master, motcorr_directory, suffix='red'+suffix)
    if brain_slave:
        save_motCorr_brain(motCorr_brain_slave, motcorr_directory, suffix='green'+suffix)

    # Save transforms
    transform_matrix = np.array(transform_matrix)
    save_file = os.path.join(motcorr_directory, 'motcorr_params{}'.format(suffix))
    np.save(save_file,transform_matrix)
Example #5
0
def get_zshift(fixed, moving):
    fixed_ants = to_ants(fixed)
    moving_ants = to_ants(moving)

    res = ants.registration(fixed_ants, moving_ants,
                            type_of_transform='Translation',
                            grad_step=.2)
    t = ants.read_transform(res['fwdtransforms'][0])
    zshift_float = t.parameters[-1]
    zshift = int(round(zshift_float))
    return zshift
Example #6
0
    def transform_coordinates(coordinates, from_imaging, to_imaging,
                              file_invMatrix):
        """coordinate transformation from one imaging modality to other; coordinates must be included as integers"""

        transformed = {'points': [], 'indices': []}
        physical_points = ants.transform_index_to_physical_point(
            from_imaging, coordinates)
        transformed['points'] = ants.apply_ants_transform(
            ants.read_transform(file_invMatrix), physical_points)
        transformed['indices'] = ants.transform_physical_point_to_index(
            image=to_imaging, point=transformed['points'])

        return transformed
Example #7
0
def transform_rois(fixed, moving, rois, **kwargs):
    def set_ifn(key, val):
        if not key in kwargs:
            kwargs[key] = val

    set_ifn('type_of_transform', 'Affine')
    set_ifn('reg_iterations', [500, 500, 500])
    set_ifn('grad_step', .1)

    res = ants.registration(fixed, moving, **kwargs)
    t = ants.read_transform(res['fwdtransforms'][0])
    xyzs = rois[:, :3]
    rs = rois[:, 3:]

    xyzs_transformed = np.array(list(map(lambda xyz: transform_xyz(t.invert(), xyz, moving, fixed), xyzs)))
    return np.concatenate([xyzs_transformed, rs], axis=1)
Example #8
0
def main(input_path, transform_path, resampled_image_path):
    if resampled_image_path is None and transform_path is None:
        raise ValueError('You must provide the path to at least one output')
    try:
        import ants
    except ImportError as e:
        message = 'Install ANTS for registration: pip install antspyx'
        raise ModuleNotFoundError(message) from e
    import numpy as np
    import torchio as tio
    reference = ants.image_read(str(tio.datasets.Colin27().t1.path))
    floating = ants.image_read(input_path)
    results = ants.registration(reference, floating, type_of_transform='Affine')
    if transform_path is not None:
        transform = ants.read_transform(results['fwdtransforms'][0])
        affine = np.eye(4)
        affine[:3] = transform.parameters.reshape(4, 3).T
        affine = tio.io._from_itk_convention(affine)
        tio.io.write_matrix(affine, transform_path)
    if resampled_image_path is not None:
        ants.image_write(results['warpedmovout'], resampled_image_path)
    return 0
Example #9
0
    def ANTsCoregisterMultiprocessing(self,
                                      file_fixed,
                                      file_moving,
                                      subj,
                                      input_folder,
                                      flag,
                                      step,
                                      status,
                                      run=1):
        """Performs Co-Registration taking advantage of multicores, i.e. multiple subjects processed in parallel"""

        status.put(tuple([file_fixed, file_moving, subj]))
        prev_reg = glob.glob(
            os.path.join(input_folder + "/" +
                         self.cfg['preprocess'][flag]['prefix'] + 'run*' +
                         os.path.basename(file_moving)))
        if not prev_reg:
            print('\tNo previous registration found, starting with first run')
            filename_save = os.path.join(
                input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' +
                str(run) + '_' + os.path.basename(file_moving))
        elif re.search(r'\w+{}.'.format('CT_'), file_moving,
                       re.IGNORECASE) and file_moving.endswith('.nii'):
            print('\tNo second run for CT-MRI registrations possible.')
            return
        else:
            allruns = [
                re.search(r'\w+(run)([\d.]+)', x).group(2) for x in prev_reg
            ]
            lastrun = int(sorted(allruns)[-1])
            file_moving = os.path.join(
                input_folder,
                self.cfg["preprocess"]["registration"]["prefix"] + 'run' +
                str(lastrun) + '_' +
                os.path.basename(file_moving))  # update for second run
            run = lastrun + 1
            n4prefix = self.cfg['preprocess']['ANTsN4']['prefix']
            basename = '{}{}'.format(n4prefix, file_moving.split(n4prefix)[1])
            filename_save = os.path.join(
                input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' +
                str(run) + '_' + basename)

        print(filename_save)
        log_filename = os.path.join(
            ROOTDIR, 'logs',
            "log_Registration_using_ANTs_{}_run_{}_".format(subj, str(run)) +
            time.strftime("%Y%m%d-%H%M%S") + '.txt')

        imaging = dict()
        for idx, file_id in enumerate([file_fixed, file_moving]):
            sequence = ants.image_read(
                file_id)  # load data and resample images if necessary
            imaging[idx] = Imaging.resampleANTs(
                mm_spacing=self.cfg['preprocess']['registration']
                ['resample_spacing'],
                ANTsImageObject=sequence,
                file_id=file_id,
                method=int(
                    self.cfg['preprocess']['registration']['resample_method']))

        if run == 1:
            metric = self.cfg['preprocess']['registration']['metric'][0]
        else:
            self.cfg['preprocess']['registration'][
                'default_registration'] = 'yes'  # TODO: must be changed if non-default works
            metric = self.cfg['preprocess']['registration']['metric'][0]

        if self.cfg['preprocess']['registration'][
                'default_registration'] == 'yes':
            registered_images = self.default_registration(imaging,
                                                          file_fixed,
                                                          file_moving,
                                                          log_filename,
                                                          metric=metric,
                                                          step=step)
        else:
            registered_images = self.custom_registration(
                imaging, file_fixed, file_moving, input_folder + '/',
                log_filename, run)

        key2rename = {
            'fwdtransforms':
            ['{}_0GenericAffineRegistration.mat'.format(step), 1],
            'invtransforms': ['{}_1InvWarpMatrix.mat'.format(step), 0]
        }
        for key, value in key2rename.items():
            Transform = ants.read_transform(registered_images[key][value[1]])
            ants.write_transform(Transform,
                                 os.path.join(input_folder, value[0]))

        ants.image_write(registered_images['warpedmovout'],
                         filename=filename_save)
        FileOperations.create_folder(os.path.join(input_folder, "debug"))

        if run > 1:  #  Previous registrations are moved to debug-folder
            prev_reg = ''.join(prev_reg) if type(
                prev_reg) == list else prev_reg
            filename_dest = re.sub(
                r'({}run[0-9]_)+({})'.format(
                    self.cfg['preprocess']['registration']['prefix'],
                    self.cfg['preprocess']['ANTsN4']['prefix']),
                '{}RUNPREV{}_{}'.format(
                    self.cfg['preprocess']['registration']['prefix'], lastrun,
                    self.cfg['preprocess']['ANTsN4']['prefix']),
                os.path.basename(prev_reg))
            shutil.move(prev_reg,
                        os.path.join(input_folder, 'debug', filename_dest))

        create_mask = True
        if create_mask and 't1' in file_moving and not os.path.isfile(
                os.path.join(input_folder, 'brainmask_T1.nii')):
            Imaging.create_brainmask(
                input_folder,
                subj=subj,
                registered_images=registered_images['warpedmovout'])
mi = ants.image_read(ants.get_data("r64"))
tx = "Affine"
pnum = 0
tx = "SyN"
pnum = 1
metrics = ["MeanSquares", "GC", "Mattes"]
asr = 1
for m in range(0, len(metrics)):
    mytx1 = ants.registration(
        fixed=fi,
        moving=mi,
        type_of_transform=tx,
        aff_metric=metrics[m],
        aff_random_sampling_rate=asr,
    )
    p1 = ants.read_transform(mytx1["fwdtransforms"][pnum])
    p1 = ants.get_ants_transform_parameters(p1)
    for k in range(0, 2):
        mytx2 = ants.registration(
            fixed=fi,
            moving=mi,
            type_of_transform=tx,
            aff_metric=metrics[m],
            aff_random_sampling_rate=asr,
        )
        p2 = ants.read_transform(mytx2["fwdtransforms"][pnum])
        p2 = ants.get_ants_transform_parameters(p2)
        metval = ants.image_mutual_information(fi, mytx2["warpedmovout"])
        chg = abs(p2 - p1).sum()
        print(metrics[m] + " Change: try " + str(k) + " Is " + str(chg) +
              " Similarity= " + str(metval))
Example #11
0
 def test_example(self):
     # test ANTsPy/ANTsR example
     fi = ants.image_read(ants.get_ants_data("r16"))
     mi = ants.image_read(ants.get_ants_data("r27"))
     txfile = ants.affine_initializer(fi, mi)
     tx = ants.read_transform(txfile, dimension=2)
Example #12
0
 def __init__(self, filename='path', **options):
     import ants
     self.tx = ants.read_transform(filename, **options)