コード例 #1
0
def extend_mask12(target, out_dir, b_value, mask=None, n_iter=200):

    command = f'N4BiasFieldCorrection -d 3 -i {target} -b {str(b_value)} -s 4 -c [{str(n_iter)}x{str(n_iter)}x{str(n_iter)},1e-4] -w {out_dir}/mask12.mnc -x {out_dir}/null_mask.mnc -o {out_dir}/corrected_lower.mnc'
    rc = run_command(command)

    command = f'ThresholdImage 3 {out_dir}/corrected_lower.mnc {out_dir}/otsu_weight.mnc Otsu 4'
    rc = run_command(command)

    otsu_img = sitk.ReadImage(f'{out_dir}/otsu_weight.mnc', sitk.sitkUInt8)
    otsu_array = sitk.GetArrayFromImage(otsu_img)

    if mask is not None:
        resampled_mask_img = sitk.ReadImage(mask, sitk.sitkUInt8)
        resampled_mask_array = sitk.GetArrayFromImage(resampled_mask_img)

        otsu_array = otsu_array * resampled_mask_array

    lower_mask = (otsu_array == 1.0) + (otsu_array == 2.0)

    def extend_mask(mask, lower_mask):
        otsu_img = sitk.ReadImage(mask, sitk.sitkUInt8)
        otsu_array = sitk.GetArrayFromImage(otsu_img)
        combined_mask = (otsu_array + lower_mask) > 0

        mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                          isVector=False)
        mask_img.CopyInformation(otsu_img)
        sitk.WriteImage(mask_img, mask)

    extend_mask(f'{out_dir}/mask12.mnc', lower_mask)
    extend_mask(f'{out_dir}/mask123.mnc', lower_mask)
    extend_mask(f'{out_dir}/mask1234.mnc', lower_mask)
コード例 #2
0
def seed_corr(bold_file, mask_file, seed):
    import os
    from rabies.utils import run_command

    brain_mask = np.asarray(nb.load(mask_file).dataobj)
    volume_indices = brain_mask.astype(bool)

    timeseries_array = np.asarray(nb.load(bold_file).dataobj)
    sub_timeseries = np.zeros(
        [timeseries_array.shape[3],
         volume_indices.sum()])
    for t in range(timeseries_array.shape[3]):
        sub_timeseries[t, :] = timeseries_array[:, :, :, t][volume_indices]

    resampled = os.path.abspath('resampled.nii.gz')
    command = f'antsApplyTransforms -i {seed} -r {mask_file} -o {resampled} -n GenericLabel'
    rc = run_command(command)

    roi_mask = np.asarray(
        nb.load(resampled).dataobj)[volume_indices].astype(bool)

    # extract the voxel timeseries within the mask, and take the mean ROI timeseries
    seed_timeseries = sub_timeseries[:, roi_mask].mean(axis=1)

    corrs = vcorrcoef(sub_timeseries.T, seed_timeseries)
    corrs[np.isnan(corrs)] = 0
    return corrs
コード例 #3
0
def otsu_bias_cor(target, otsu_ref, out_dir, b_value, mask=None, n_iter=200):
    command = f'ImageMath 3 {out_dir}/null_mask.mnc ThresholdAtMean {otsu_ref} 0'
    rc = run_command(command)
    command = f'ThresholdImage 3 {otsu_ref} {out_dir}/otsu_weight.mnc Otsu 4'
    rc = run_command(command)

    otsu_img = sitk.ReadImage(f'{out_dir}/otsu_weight.mnc', sitk.sitkUInt8)
    otsu_array = sitk.GetArrayFromImage(otsu_img)

    if mask is not None:
        resampled_mask_img = sitk.ReadImage(mask, sitk.sitkUInt8)
        resampled_mask_array = sitk.GetArrayFromImage(resampled_mask_img)

        otsu_array = otsu_array * resampled_mask_array

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, f'{out_dir}/mask12.mnc')

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + (otsu_array
                                                                 == 3.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, f'{out_dir}/mask123.mnc')

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + (
        otsu_array == 3.0) + (otsu_array == 4.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, f'{out_dir}/mask1234.mnc')

    extend_mask12(target, out_dir, b_value=b_value, mask=mask, n_iter=200)

    command = f'N4BiasFieldCorrection -v -d 3 -i {target} -b {str(b_value)} -s 4 -c [{str(n_iter)}x{str(n_iter)}x{str(n_iter)},1e-4] -w {out_dir}/mask12.mnc -x {out_dir}/null_mask.mnc -o {out_dir}/corrected1_.mnc'
    rc = run_command(command)

    #command = 'N4BiasFieldCorrection -v -d 3 -i corrected1_.mnc -b %s -s 4 -c [%sx%sx%s,1e-4] -w mask123.mnc -x null_mask.mnc -o corrected2_.mnc' % (str(b_value), str(n_iter),str(n_iter),str(n_iter),)
    #rc = run_command(command)

    command = f'N4BiasFieldCorrection -v -d 3 -i {out_dir}/corrected1_.mnc -b {str(b_value)} -s 4 -c [{str(n_iter)}x{str(n_iter)}x{str(n_iter)},1e-4] -w {out_dir}/mask1234.mnc -x {out_dir}/null_mask.mnc -o {out_dir}/multistage_corrected.mnc'
    rc = run_command(command)
コード例 #4
0
    def _run_interface(self, runtime):
        filename_template = pathlib.Path(
            self.inputs.name_source).name.rsplit(".nii")[0]

        script_path = 'plot_overlap.sh'
        os.makedirs(self.inputs.out_dir, exist_ok=True)
        out_name = self.inputs.out_dir+'/' + \
            filename_template+'_registration.png'

        command = f'{script_path} {self.inputs.moving} {self.inputs.fixed} {out_name}'
        rc = run_command(command)

        setattr(self, 'out_png', out_name)
        return runtime
コード例 #5
0
def run_group_ICA(bold_file_list, mask_file, dim, random_seed):
    import os
    import pandas as pd

    # create a filelist.txt
    file_path = os.path.abspath('filelist.txt')
    from rabies.utils import flatten_list
    merged = flatten_list(list(bold_file_list))
    df = pd.DataFrame(data=merged)
    df.to_csv(file_path, header=False, sep=',', index=False)

    from rabies.utils import run_command
    out_dir = os.path.abspath('group_melodic.ica')
    command = f'melodic -i {file_path} -m {mask_file} -o {out_dir} -d {dim} --report --seed={str(random_seed)}'
    rc = run_command(command)
    IC_file = out_dir + '/melodic_IC.nii.gz'
    return out_dir, IC_file
コード例 #6
0
ファイル: registration.py プロジェクト: CoBrALab/RABIES
def run_antsRegistration(reg_method,
                         brain_extraction=False,
                         moving_image='NULL',
                         moving_mask='NULL',
                         fixed_image='NULL',
                         fixed_mask='NULL',
                         rabies_data_type=8):
    import os
    import pathlib  # Better path manipulation
    filename_split = pathlib.Path(moving_image).name.rsplit(".nii")

    from rabies.preprocess_pkg.registration import define_reg_script
    reg_call = define_reg_script(reg_method)

    if reg_method == 'Rigid' or reg_method == 'Affine' or reg_method == 'SyN':
        if brain_extraction:
            reg_call += " --mask-extract --keep-mask-after-extract"
        command = f"{reg_call} --moving-mask {moving_mask} --fixed-mask {fixed_mask} --resampled-output {filename_split[0]}_output_warped_image.nii.gz {moving_image} {fixed_image} {filename_split[0]}_output_"
    else:
        command = f'{reg_call} {moving_image} {moving_mask} {fixed_image} {fixed_mask} {filename_split[0]}'
    from rabies.utils import run_command
    rc = run_command(command)

    cwd = os.getcwd()
    warped_image = f'{cwd}/{filename_split[0]}_output_warped_image.nii.gz'
    affine = f'{cwd}/{filename_split[0]}_output_0GenericAffine.mat'
    warp = f'{cwd}/{filename_split[0]}_output_1Warp.nii.gz'
    inverse_warp = f'{cwd}/{filename_split[0]}_output_1InverseWarp.nii.gz'
    if not os.path.isfile(warped_image) or not os.path.isfile(affine):
        raise ValueError(
            'REGISTRATION ERROR: OUTPUT FILES MISSING. Make sure the provided registration script runs properly.'
        )
    if not os.path.isfile(warp) or not os.path.isfile(inverse_warp):
        from nipype import logging
        log = logging.getLogger('nipype.workflow')
        log.debug(
            'No non-linear warp files as output. Assumes linear registration.')
        warp = 'NULL'
        inverse_warp = 'NULL'

    import SimpleITK as sitk
    sitk.WriteImage(sitk.ReadImage(warped_image, rabies_data_type),
                    warped_image)

    return [affine, warp, inverse_warp, warped_image]
コード例 #7
0
def otsu_scaling(image_file):
    img = sitk.ReadImage(image_file)
    array = sitk.GetArrayFromImage(img)

    # select a smart vmax for the image display to enhance contrast
    command = f'ThresholdImage 3 {image_file} otsu_weight.nii.gz Otsu 4'
    rc = run_command(command)

    # clip off the background
    mask = sitk.GetArrayFromImage(sitk.ReadImage('otsu_weight.nii.gz'))
    voxel_subset = array[mask > 1.0]

    # select a maximal value which encompasses 90% of the voxels in the mask
    voxel_subset.sort()
    vmax = voxel_subset[int(len(voxel_subset) * 0.9)]

    scaled = array / vmax
    scaled_img = sitk.GetImageFromArray(scaled, isVector=False)
    scaled_img.CopyInformation(img)
    return scaled_img
コード例 #8
0
def resample_4D(input_4d, ref_file):
    import os
    import pathlib  # Better path manipulation
    import SimpleITK as sitk
    from rabies.utils import run_command, split_volumes, Merge, copyInfo_3DImage
    rabies_data_type = sitk.sitkFloat32

    # check if the IC_file has the same dimensions as bold_file
    img_array = sitk.GetArrayFromImage(sitk.ReadImage(ref_file))[0, :, :, :]
    image_3d = copyInfo_3DImage(
        sitk.GetImageFromArray(img_array, isVector=False),
        sitk.ReadImage(ref_file))
    new_ref = 'temp_ref.nii.gz'
    sitk.WriteImage(image_3d, 'temp_ref.nii.gz')

    filename_split = pathlib.Path(input_4d).name.rsplit(".nii")

    # Splitting into list of single volumes
    [split_volumes_files, num_volumes] = split_volumes(input_4d, "split_",
                                                       rabies_data_type)

    resampled_volumes = []
    for x in range(0, num_volumes):
        resampled_vol_fname = os.path.abspath("resampled_volume" + str(x) +
                                              ".nii.gz")
        resampled_volumes.append(resampled_vol_fname)

        command = f'antsApplyTransforms -i {split_volumes_files[x]} -n BSpline[5] -r {new_ref} -o {resampled_vol_fname}'
        rc = run_command(command)
        # change image to specified data type
        sitk.WriteImage(sitk.ReadImage(resampled_vol_fname, rabies_data_type),
                        resampled_vol_fname)

    out = Merge(in_files=resampled_volumes,
                header_source=input_4d,
                rabies_data_type=rabies_data_type,
                clip_negative=False).run()
    return out.outputs.out_file
コード例 #9
0
def resample_mask(in_file, ref_file):
    transforms = []
    inverses = []
    # resampling the reference image to the dimension of the EPI
    from rabies.utils import run_command
    import pathlib  # Better path manipulation
    filename_split = pathlib.Path(
        in_file).name.rsplit(".nii")
    out_file = os.path.abspath(filename_split[0])+'_resampled.nii.gz'

    # tranforms is a list of transform files, set in order of call within antsApplyTransforms
    transform_string = ""
    for transform, inverse in zip(transforms, inverses):
        if transform == 'NULL':
            continue
        elif bool(inverse):
            transform_string += f"-t [{transform},1] "
        else:
            transform_string += f"-t {transform} "

    command = f'antsApplyTransforms -i {in_file} {transform_string}-n GenericLabel -r {ref_file} -o {out_file}'
    rc = run_command(command)
    return out_file
コード例 #10
0
def otsu_bias_cor(target, otsu_ref, out_name, b_value, mask=None, n_iter=200):
    import SimpleITK as sitk
    from rabies.utils import run_command
    command = 'ImageMath 3 null_mask.nii.gz ThresholdAtMean %s 0' % (otsu_ref)
    rc = run_command(command)
    command = 'ThresholdImage 3 %s otsu_weight.nii.gz Otsu 4' % (otsu_ref)
    rc = run_command(command)

    otsu_img = sitk.ReadImage('otsu_weight.nii.gz', sitk.sitkUInt8)
    otsu_array = sitk.GetArrayFromImage(otsu_img)

    if mask is not None:
        resampled_mask_img = sitk.ReadImage(mask, sitk.sitkUInt8)
        resampled_mask_array = sitk.GetArrayFromImage(resampled_mask_img)

        otsu_array = otsu_array * resampled_mask_array

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, 'mask12.nii.gz')

    combined_mask = (otsu_array == 3.0) + (otsu_array == 4.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, 'mask34.nii.gz')

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + (otsu_array
                                                                 == 3.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, 'mask123.nii.gz')

    combined_mask = (otsu_array == 2.0) + (otsu_array == 3.0) + (otsu_array
                                                                 == 4.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, 'mask234.nii.gz')

    combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + (
        otsu_array == 3.0) + (otsu_array == 4.0)
    mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'),
                                      isVector=False)
    mask_img.CopyInformation(otsu_img)
    sitk.WriteImage(mask_img, 'mask1234.nii.gz')

    command = 'N4BiasFieldCorrection -d 3 -i %s -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask12.nii.gz -x null_mask.nii.gz -o corrected1.nii.gz' % (
        target,
        str(b_value),
        str(n_iter),
        str(n_iter),
        str(n_iter),
    )
    rc = run_command(command)

    command = 'N4BiasFieldCorrection -d 3 -i corrected1.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask34.nii.gz -x null_mask.nii.gz -o corrected2.nii.gz' % (
        str(b_value),
        str(n_iter),
        str(n_iter),
        str(n_iter),
    )
    rc = run_command(command)

    command = 'N4BiasFieldCorrection -d 3 -i corrected2.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask123.nii.gz -x null_mask.nii.gz -o corrected3.nii.gz' % (
        str(b_value),
        str(n_iter),
        str(n_iter),
        str(n_iter),
    )
    rc = run_command(command)

    command = 'N4BiasFieldCorrection -d 3 -i corrected3.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask234.nii.gz -x null_mask.nii.gz -o corrected4.nii.gz' % (
        str(b_value),
        str(n_iter),
        str(n_iter),
        str(n_iter),
    )
    rc = run_command(command)

    command = 'N4BiasFieldCorrection -d 3 -i corrected4.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask1234.nii.gz -x null_mask.nii.gz -o %s' % (
        str(b_value),
        str(n_iter),
        str(n_iter),
        str(n_iter),
        out_name,
    )
    rc = run_command(command)
コード例 #11
0
    def _run_interface(self, runtime):
        import os
        import numpy as np
        import SimpleITK as sitk

        import pathlib  # Better path manipulation
        filename_split = pathlib.Path(
            self.inputs.name_source).name.rsplit(".nii")

        from rabies.utils import run_command, resample_image_spacing
        from rabies.preprocess_pkg.registration import run_antsRegistration

        cwd = os.getcwd()
        resampled = '%s/%s_resampled.nii.gz' % (cwd, filename_split[0])
        resampled_mask = '%s/%s_resampled_mask.nii.gz' % (cwd,
                                                          filename_split[0])
        biascor_EPI = '%s/%s_bias_cor.nii.gz' % (
            cwd,
            filename_split[0],
        )

        # resample to isotropic resolution based on lowest dimension
        input_ref_EPI_img = sitk.ReadImage(self.inputs.input_ref_EPI,
                                           self.inputs.rabies_data_type)
        dim = input_ref_EPI_img.GetSpacing()
        low_dim = np.asarray(dim).min()
        #sitk.WriteImage(resample_image_spacing(
        #    input_ref_EPI_img, (low_dim, low_dim, low_dim)), resampled)

        # the -b will be rounded up to the nearest multiple of 10 of the image largest dimension
        largest_dim = (np.array(input_ref_EPI_img.GetSize()) *
                       np.array(input_ref_EPI_img.GetSpacing())).max()
        b_value = int(np.ceil(largest_dim / 10) * 10)

        bias_cor_input = self.inputs.input_ref_EPI
        otsu_bias_cor(target=bias_cor_input,
                      otsu_ref=bias_cor_input,
                      out_name=cwd + '/corrected_iter1.nii.gz',
                      b_value=b_value)
        otsu_bias_cor(target=bias_cor_input,
                      otsu_ref=cwd + '/corrected_iter1.nii.gz',
                      out_name=cwd + '/corrected_iter2.nii.gz',
                      b_value=b_value)

        [affine, warp, inverse_warp, warped_image
         ] = run_antsRegistration(reg_method='Rigid',
                                  moving_image=cwd + '/corrected_iter2.nii.gz',
                                  fixed_image=self.inputs.anat,
                                  fixed_mask=self.inputs.anat_mask)

        command = 'antsApplyTransforms -d 3 -i %s -t [%s,1] -r %s -o %s -n GenericLabel' % (
            self.inputs.anat_mask, affine, cwd + '/corrected_iter2.nii.gz',
            resampled_mask)
        rc = run_command(command)

        otsu_bias_cor(target=bias_cor_input,
                      otsu_ref=cwd + '/corrected_iter2.nii.gz',
                      out_name=cwd + '/final_otsu.nii.gz',
                      b_value=b_value,
                      mask=resampled_mask)

        # resample to anatomical image resolution
        dim = sitk.ReadImage(self.inputs.anat,
                             self.inputs.rabies_data_type).GetSpacing()
        low_dim = np.asarray(dim).min()
        sitk.WriteImage(
            resample_image_spacing(
                sitk.ReadImage(cwd + '/final_otsu.nii.gz',
                               self.inputs.rabies_data_type),
                (low_dim, low_dim, low_dim)), biascor_EPI)

        sitk.WriteImage(
            sitk.ReadImage(cwd + '/corrected_iter2.nii.gz',
                           self.inputs.rabies_data_type),
            cwd + '/corrected_iter2.nii.gz')
        sitk.WriteImage(
            sitk.ReadImage(biascor_EPI, self.inputs.rabies_data_type),
            biascor_EPI)
        sitk.WriteImage(
            sitk.ReadImage(warped_image, self.inputs.rabies_data_type),
            warped_image)
        sitk.WriteImage(
            sitk.ReadImage(resampled_mask, self.inputs.rabies_data_type),
            resampled_mask)

        setattr(self, 'init_denoise', cwd + '/corrected_iter2.nii.gz')
        setattr(self, 'corrected_EPI', biascor_EPI)
        setattr(self, 'warped_EPI', warped_image)
        setattr(self, 'denoise_mask', resampled_mask)

        return runtime
コード例 #12
0
    def _run_interface(self, runtime):
        import os
        import numpy as np
        import SimpleITK as sitk
        from rabies.utils import resample_image_spacing, run_command

        import pathlib  # Better path manipulation
        filename_split = pathlib.Path(
            self.inputs.name_source).name.rsplit(".nii")
        cwd = os.getcwd()

        # resample the anatomical image to the resolution of the provided template
        target_img = sitk.ReadImage(self.inputs.target_img,
                                    self.inputs.rabies_data_type)
        if not target_img.GetDimension() == 3:
            raise ValueError(
                f"Input image {self.inputs.target_img} is not 3-dimensional.")
        anat_dim = target_img.GetSpacing()

        template_image = sitk.ReadImage(self.inputs.anat_ref,
                                        self.inputs.rabies_data_type)
        template_dim = template_image.GetSpacing()
        if not (np.array(anat_dim) == np.array(template_dim)).sum() == 3:
            from nipype import logging
            log = logging.getLogger('nipype.workflow')
            log.debug(
                'Anat image will be resampled to the template resolution.')
            resampled = resample_image_spacing(target_img, template_dim)
            target_img = f'{cwd}/{filename_split[0]}_resampled.nii.gz'
            sitk.WriteImage(resampled, target_img)
        else:
            target_img = self.inputs.target_img

        if self.inputs.inho_cor_method == 'disable':
            # outputs correspond to the inputs
            corrected = target_img
            init_denoise = corrected
            resampled_mask = self.inputs.anat_mask
        elif self.inputs.inho_cor_method in [
                'Rigid', 'Affine', 'SyN', 'no_reg'
        ]:
            corrected = f'{cwd}/{filename_split[0]}_inho_cor.nii.gz'
            if self.inputs.image_type == 'EPI':
                processing_script = 'EPI-preprocessing.sh'
            elif self.inputs.image_type == 'structural':
                processing_script = 'structural-preprocessing.sh'
            else:
                raise ValueError(
                    f"Image type must be 'EPI' or 'structural', {self.inputs.image_type}"
                )
            command = f'{processing_script} {target_img} {corrected} {self.inputs.anat_ref} {self.inputs.anat_mask} {self.inputs.inho_cor_method} {self.inputs.multistage_otsu} {str(self.inputs.otsu_threshold)}'
            rc = run_command(command)

            resampled_mask = corrected.split('.nii.gz')[0] + '_mask.nii.gz'
            init_denoise = corrected.split(
                '.nii.gz')[0] + '_init_denoise.nii.gz'
        elif self.inputs.inho_cor_method in ['N4_reg']:
            if self.inputs.image_type == 'EPI':

                bias_correction = OtsuEPIBiasCorrection(
                    input_ref_EPI=target_img,
                    anat=self.inputs.anat_ref,
                    anat_mask=self.inputs.anat_mask,
                    name_source=self.inputs.name_source,
                    rabies_data_type=self.inputs.rabies_data_type)
                out = bias_correction.run()
                corrected = out.outputs.corrected_EPI
                resampled_mask = out.outputs.denoise_mask
                init_denoise = out.outputs.init_denoise

            elif self.inputs.image_type == 'structural':
                corrected = f'{cwd}/{filename_split[0]}_inho_cor.nii.gz'
                input_anat = target_img

                command = 'ImageMath 3 null_mask.nii.gz ThresholdAtMean %s 0' % (
                    input_anat)
                rc = run_command(command)
                command = 'ImageMath 3 thresh_mask.nii.gz ThresholdAtMean %s 1.2' % (
                    input_anat)
                rc = run_command(command)

                command = 'N4BiasFieldCorrection -d 3 -s 4 -i %s -b [20] -c [200x200x200,0.0] -w thresh_mask.nii.gz -x null_mask.nii.gz -o N4.nii.gz' % (
                    input_anat)
                rc = run_command(command)
                command = 'DenoiseImage -d 3 -i N4.nii.gz -o denoise.nii.gz'
                rc = run_command(command)

                from rabies.preprocess_pkg.registration import run_antsRegistration
                [affine, warp, inverse_warp, warped_image
                 ] = run_antsRegistration(reg_method='Affine',
                                          moving_image=input_anat,
                                          fixed_image=self.inputs.anat_ref,
                                          fixed_mask=self.inputs.anat_mask)

                command = 'antsApplyTransforms -d 3 -i %s -t [%s,1] -r %s -o resampled_mask.nii.gz -n GenericLabel' % (
                    self.inputs.anat_mask, affine, input_anat)
                rc = run_command(command)

                command = 'N4BiasFieldCorrection -d 3 -s 2 -i %s -b [20] -c [200x200x200x200,0.0] -w resampled_mask.nii.gz -r 1 -x null_mask.nii.gz -o N4.nii.gz' % (
                    input_anat)
                rc = run_command(command)
                command = 'DenoiseImage -d 3 -i N4.nii.gz -o %s' % (corrected)
                rc = run_command(command)

                # resample image to specified data format
                sitk.WriteImage(
                    sitk.ReadImage(corrected, self.inputs.rabies_data_type),
                    corrected)
                init_denoise = cwd + '/denoise.nii.gz'
                resampled_mask = cwd + '/resampled_mask.nii.gz'

            else:
                raise ValueError(
                    f"Image type must be 'EPI' or 'structural', {self.inputs.image_type}"
                )

        else:
            raise ValueError("Wrong inho_cor_method.")

        # resample image to specified data format
        sitk.WriteImage(
            sitk.ReadImage(corrected, self.inputs.rabies_data_type), corrected)

        setattr(self, 'corrected', corrected)
        setattr(self, 'init_denoise', init_denoise)
        setattr(self, 'denoise_mask', resampled_mask)
        return runtime
コード例 #13
0
ファイル: bold_ref.py プロジェクト: CoBrALab/RABIES
    def _run_interface(self, runtime):

        from nipype import logging
        log = logging.getLogger('nipype.workflow')

        in_nii = sitk.ReadImage(self.inputs.in_file,
                                self.inputs.rabies_data_type)
        if not in_nii.GetDimension()==4:
            raise ValueError(f"Input image {self.inputs.in_file} is not 4-dimensional.")

        data_slice = sitk.GetArrayFromImage(in_nii)[:50, :, :, :]

        n_volumes_to_discard = _get_vols_to_discard(in_nii)

        filename_split = pathlib.Path(self.inputs.in_file).name.rsplit(".nii")
        out_ref_fname = os.path.abspath(
            f'{filename_split[0]}_bold_ref.nii.gz')

        if (not n_volumes_to_discard == 0) and self.inputs.detect_dummy:
            log.info("Detected "+str(n_volumes_to_discard)
                  + " dummy scans. Taking the median of these volumes as reference EPI.")
            median_image_data = np.median(
                data_slice[:n_volumes_to_discard, :, :, :], axis=0)

            out_bold_file = os.path.abspath(
                f'{filename_split[0]}_cropped_dummy.nii.gz')
            img_array = sitk.GetArrayFromImage(
                in_nii)[n_volumes_to_discard:, :, :, :]

            image_4d = copyInfo_4DImage(sitk.GetImageFromArray(
                img_array, isVector=False), in_nii, in_nii)
            sitk.WriteImage(image_4d, out_bold_file)

        else:
            out_bold_file = self.inputs.in_file

            n_volumes_to_discard = 0
            if self.inputs.detect_dummy:
                log.info(
                    "Detected no dummy scans. Generating the ref EPI based on multiple volumes.")
            # if no dummy scans, will generate a median from a subset of max 100
            # slices of the time series
            if in_nii.GetSize()[-1] > 100:
                slice_fname = os.path.abspath("slice.nii.gz")
                image_4d = copyInfo_4DImage(sitk.GetImageFromArray(
                    data_slice[20:100, :, :, :], isVector=False), in_nii, in_nii)
                sitk.WriteImage(image_4d, slice_fname)
                median_fname = os.path.abspath("median.nii.gz")
                image_3d = copyInfo_3DImage(sitk.GetImageFromArray(
                    np.median(data_slice[20:100, :, :, :], axis=0), isVector=False), in_nii)
                sitk.WriteImage(image_3d, median_fname)
            else:
                slice_fname = self.inputs.in_file
                median_fname = os.path.abspath("median.nii.gz")
                image_3d = copyInfo_3DImage(sitk.GetImageFromArray(
                    np.median(data_slice, axis=0), isVector=False), in_nii)
                sitk.WriteImage(image_3d, median_fname)

            # First iteration to generate reference image.
            res = antsMotionCorr(in_file=slice_fname,
                                 ref_file=median_fname, prebuilt_option=self.inputs.HMC_option, transform_type='Rigid', second=False, rabies_data_type=self.inputs.rabies_data_type).run()

            median = np.median(sitk.GetArrayFromImage(sitk.ReadImage(
                res.outputs.mc_corrected_bold, self.inputs.rabies_data_type)), axis=0)
            tmp_median_fname = os.path.abspath("tmp_median.nii.gz")
            image_3d = copyInfo_3DImage(
                sitk.GetImageFromArray(median, isVector=False), in_nii)
            sitk.WriteImage(image_3d, tmp_median_fname)

            # Second iteration to generate reference image.
            res = antsMotionCorr(in_file=slice_fname,
                                 ref_file=tmp_median_fname, prebuilt_option=self.inputs.HMC_option, transform_type='Rigid', second=True,  rabies_data_type=self.inputs.rabies_data_type).run()

            # evaluate a trimmed mean instead of a median, trimming the 5% extreme values
            from scipy import stats
            median_image_data = stats.trim_mean(sitk.GetArrayFromImage(sitk.ReadImage(
                res.outputs.mc_corrected_bold, self.inputs.rabies_data_type)), 0.05, axis=0)

        # median_image_data is a 3D array of the median image, so creates a new nii image
        # saves it
        image_3d = copyInfo_3DImage(sitk.GetImageFromArray(
            median_image_data, isVector=False), in_nii)
        sitk.WriteImage(image_3d, out_ref_fname)

        # denoise the resulting reference image through non-local mean denoising
        # Denoising reference image.
        command = f'DenoiseImage -d 3 -i {out_ref_fname} -o {out_ref_fname}'
        rc = run_command(command)

        setattr(self, 'ref_image', out_ref_fname)
        setattr(self, 'bold_file', out_bold_file)

        return runtime
コード例 #14
0
ファイル: stc.py プロジェクト: CoBrALab/RABIES
def slice_timing_correction(in_file,
                            tr='auto',
                            tpattern='alt',
                            rabies_data_type=8):
    '''
    This functions applies slice-timing correction on the anterior-posterior
    slice acquisition direction. The input image, assumed to be in RAS orientation
    (accoring to nibabel; note that the nibabel reading of RAS corresponds to
     LPI for AFNI). The A and S dimensions will be swapped to apply AFNI's
    3dTshift STC with a quintic fitting function, which can only be applied to
    the Z dimension of the data matrix. The corrected image is then re-created with
    proper axes and the corrected timeseries.

    **Inputs**

        in_file
            BOLD series NIfTI file in RAS orientation.
        ignore
            Number of non-steady-state volumes detected at beginning of ``bold_file``
        tr
            TR of the BOLD image.
        tpattern
            Input to AFNI's 3dTshift -tpattern option, which specifies the
            directionality of slice acquisition, or whether it is sequential or
            interleaved.

    **Outputs**

        out_file
            Slice-timing corrected BOLD series NIfTI file

    '''

    import os
    import SimpleITK as sitk
    import numpy as np

    if tpattern == "alt":
        tpattern = 'alt-z'
    elif tpattern == "seq":
        tpattern = 'seq-z'
    else:
        raise ValueError('Invalid --tpattern provided.')

    img = sitk.ReadImage(in_file, rabies_data_type)

    if tr == 'auto':
        tr = str(img.GetSpacing()[3]) + 's'
    else:
        tr = str(tr) + 's'

    # get image data
    img_array = sitk.GetArrayFromImage(img)

    shape = img_array.shape
    new_array = np.zeros([shape[0], shape[2], shape[1], shape[3]])
    for i in range(shape[2]):
        new_array[:, i, :, :] = img_array[:, :, i, :]

    image_out = sitk.GetImageFromArray(new_array, isVector=False)
    sitk.WriteImage(image_out, 'STC_temp.nii.gz')

    command = f'3dTshift -quintic -prefix temp_tshift.nii.gz -tpattern {tpattern} -TR {tr} STC_temp.nii.gz'
    from rabies.utils import run_command
    rc = run_command(command)

    tshift_img = sitk.ReadImage('temp_tshift.nii.gz', rabies_data_type)
    tshift_array = sitk.GetArrayFromImage(tshift_img)

    new_array = np.zeros(shape)
    for i in range(shape[2]):
        new_array[:, :, i, :] = tshift_array[:, i, :, :]
    image_out = sitk.GetImageFromArray(new_array, isVector=False)

    from rabies.utils import copyInfo_4DImage
    image_out = copyInfo_4DImage(image_out, img, img)

    import pathlib  # Better path manipulation
    filename_split = pathlib.Path(in_file).name.rsplit(".nii")
    out_file = os.path.abspath(filename_split[0] + '_tshift.nii.gz')
    sitk.WriteImage(image_out, out_file)
    return out_file
コード例 #15
0
    def _run_interface(self, runtime):
        import os
        import pandas as pd
        import pathlib
        import multiprocessing

        cwd = os.getcwd()
        template_folder = self.inputs.output_folder

        command = f'mkdir -p {template_folder}'
        rc = run_command(command)

        merged = flatten_list(list(self.inputs.moving_image_list))
        # create a csv file of the input image list
        csv_path = cwd + '/commonspace_input_files.csv'
        df = pd.DataFrame(data=merged)
        df.to_csv(csv_path, header=False, sep=',', index=False)

        if self.inputs.masking:
            merged_masks = flatten_list(list(self.inputs.moving_mask_list))
            mask_csv_path = cwd + '/commonspace_input_masks.csv'
            df = pd.DataFrame(data=merged_masks)
            df.to_csv(mask_csv_path, header=False, sep=',', index=False)
            masks = f'--masks {mask_csv_path}'
        else:
            merged_masks = ['NULL']
            masks = ''
            unbiased_mask = 'NULL'

        if len(merged) == 1:
            from nipype import logging
            log = logging.getLogger('nipype.workflow')
            log.info(
                "Only a single scan was provided as input for commonspace registration. Commonspace registration "
                "won't be run, and the output template will be the input scan."
            )

            # create an identity transform as a surrogate for the commonspace transforms
            import SimpleITK as sitk
            dimension = 3
            identity = sitk.Transform(dimension, sitk.sitkIdentity)

            file = merged[0]
            mask = merged_masks[0]
            filename_template = pathlib.Path(file).name.rsplit(".nii")[0]
            transform_file = template_folder + filename_template + '_identity.mat'
            sitk.WriteTransform(identity, transform_file)

            setattr(self, 'unbiased_template', file)
            setattr(self, 'unbiased_mask', mask)
            setattr(self, 'affine_list', [transform_file])
            setattr(self, 'warp_list', [transform_file])
            setattr(self, 'inverse_warp_list', [transform_file])
            setattr(self, 'warped_image_list', [file])

            return runtime

        # convert nipype plugin spec to match QBATCH
        plugin = self.inputs.cluster_type
        if plugin == 'MultiProc' or plugin == 'Linear':
            cluster_type = 'local'
            num_threads = multiprocessing.cpu_count()
        elif plugin == 'SGE' or plugin == 'SGEGraph':
            cluster_type = 'sge'
            num_threads = 1
        elif plugin == 'PBS':
            cluster_type = 'PBS'
            num_threads = 1
        elif plugin == 'SLURM' or plugin == 'SLURMGraph':
            cluster_type = 'slurm'
            num_threads = 1
        else:
            raise ValueError(
                "Plugin option must correspond to one of 'local', 'sge', 'pbs' or 'slurm'"
            )

        command = f'QBATCH_SYSTEM={cluster_type} QBATCH_CORES={num_threads} modelbuild.sh \
            --float --average-type median --gradient-step 0.25 --iterations 2 --starting-target {self.inputs.template_anat} --stages rigid,affine,nlin \
            --output-dir {template_folder} --sharpen-type unsharp --block --debug {masks} {csv_path}'

        rc = run_command(command)


        unbiased_template = template_folder + \
            '/nlin/1/average/template_sharpen_shapeupdate.nii.gz'
        # verify that all outputs are present
        if not os.path.isfile(unbiased_template):
            raise ValueError(unbiased_template + " doesn't exists.")

        if self.inputs.masking:
            unbiased_mask = template_folder + \
                '/nlin/1/average/mask_shapeupdate.nii.gz'
            # verify that all outputs are present
            if not os.path.isfile(unbiased_mask):
                raise ValueError(unbiased_mask + " doesn't exists.")

        affine_list = []
        warp_list = []
        inverse_warp_list = []
        warped_image_list = []

        i = 0
        for file in merged:
            file = str(file)
            filename_template = pathlib.Path(file).name.rsplit(".nii")[0]
            native_to_unbiased_inverse_warp = f'{template_folder}/nlin/1/transforms/{filename_template}_1InverseWarp.nii.gz'
            if not os.path.isfile(native_to_unbiased_inverse_warp):
                raise ValueError(native_to_unbiased_inverse_warp +
                                 " file doesn't exists.")
            native_to_unbiased_warp = f'{template_folder}/nlin/1/transforms/{filename_template}_1Warp.nii.gz'
            if not os.path.isfile(native_to_unbiased_warp):
                raise ValueError(native_to_unbiased_warp +
                                 " file doesn't exists.")
            native_to_unbiased_affine = f'{template_folder}/nlin/1/transforms/{filename_template}_0GenericAffine.mat'
            if not os.path.isfile(native_to_unbiased_affine):
                raise ValueError(native_to_unbiased_affine +
                                 " file doesn't exists.")
            warped_image = f'{template_folder}/nlin/1/resample/{filename_template}.nii.gz'
            if not os.path.isfile(warped_image):
                raise ValueError(warped_image + " file doesn't exists.")
            inverse_warp_list.append(native_to_unbiased_inverse_warp)
            warp_list.append(native_to_unbiased_warp)
            affine_list.append(native_to_unbiased_affine)
            warped_image_list.append(warped_image)
            i += 1

        setattr(self, 'unbiased_template', unbiased_template)
        setattr(self, 'unbiased_mask', unbiased_mask)
        setattr(self, 'affine_list', affine_list)
        setattr(self, 'warp_list', warp_list)
        setattr(self, 'inverse_warp_list', inverse_warp_list)
        setattr(self, 'warped_image_list', warped_image_list)

        return runtime
コード例 #16
0
ファイル: confounds.py プロジェクト: CoBrALab/RABIES
    def _run_interface(self, runtime):
        import numpy as np
        import os
        from rabies.utils import run_command
        import pathlib  # Better path manipulation
        filename_split = pathlib.Path(self.inputs.bold).name.rsplit(".nii")

        # generate a .nii file representing the positioning or framewise displacement for each voxel within the brain_mask
        # first the voxelwise positioning map
        command = f'antsMotionCorrStats -m {self.inputs.movpar_file} -o {filename_split[0]}_pos_file.csv -x {self.inputs.brain_mask} \
                    -d {self.inputs.bold} -s {filename_split[0]}_pos_voxelwise.nii.gz'

        rc = run_command(command)
        pos_voxelwise = os.path.abspath(f"{filename_split[0]}_pos_file.nii.gz")

        # then the voxelwise framewise displacement map
        command = f'antsMotionCorrStats -m {self.inputs.movpar_file} -o {filename_split[0]}_FD_file.csv -x {self.inputs.brain_mask} \
                    -d {self.inputs.bold} -s {filename_split[0]}_FD_voxelwise.nii.gz -f 1'

        rc = run_command(command)

        FD_csv = os.path.abspath(f"{filename_split[0]}_FD_file.csv")
        FD_voxelwise = os.path.abspath(f"{filename_split[0]}_FD_file.nii.gz")

        confounds = []
        csv_columns = []
        WM_signal = extract_mask_trace(self.inputs.bold, self.inputs.WM_mask)
        confounds.append(WM_signal)
        csv_columns += ['WM_signal']

        CSF_signal = extract_mask_trace(self.inputs.bold, self.inputs.CSF_mask)
        confounds.append(CSF_signal)
        csv_columns += ['CSF_signal']

        vascular_signal = extract_mask_trace(self.inputs.bold,
                                             self.inputs.vascular_mask)
        confounds.append(vascular_signal)
        csv_columns += ['vascular_signal']

        [aCompCor, num_comp
         ] = compute_aCompCor(self.inputs.bold,
                              self.inputs.WM_mask,
                              self.inputs.CSF_mask,
                              method=self.inputs.aCompCor_method,
                              rabies_data_type=self.inputs.rabies_data_type)
        for param in range(aCompCor.shape[1]):
            confounds.append(aCompCor[:, param])
        comp_column = []
        for comp in range(num_comp):
            comp_column.append('aCompCor' + str(comp + 1))
        csv_columns += comp_column

        global_signal = extract_mask_trace(self.inputs.bold,
                                           self.inputs.brain_mask)
        confounds.append(global_signal)
        csv_columns += ['global_signal']
        motion_24 = motion_24_params(self.inputs.movpar_file)
        for param in range(motion_24.shape[1]):
            confounds.append(motion_24[:, param])
        csv_columns += [
            'mov1', 'mov2', 'mov3', 'rot1', 'rot2', 'rot3', 'mov1_der',
            'mov2_der', 'mov3_der', 'rot1_der', 'rot2_der', 'rot3_der',
            'mov1^2', 'mov2^2', 'mov3^2', 'rot1^2', 'rot2^2', 'rot3^2',
            'mov1_der^2', 'mov2_der^2', 'mov3_der^2', 'rot1_der^2',
            'rot2_der^2', 'rot3_der^2'
        ]

        confounds_csv = write_confound_csv(np.transpose(np.asarray(confounds)),
                                           csv_columns, filename_split[0])

        setattr(self, 'FD_csv', FD_csv)
        setattr(self, 'FD_voxelwise', FD_voxelwise)
        setattr(self, 'pos_voxelwise', pos_voxelwise)
        setattr(self, 'confounds_csv', confounds_csv)
        return runtime