Esempio n. 1
0
def recover_4D(mask_file, vector_maps, ref_4d):
    from rabies.utils import copyInfo_4DImage
    #vector maps of shape num_volumeXnum_voxel
    mask_img = sitk.ReadImage(mask_file, sitk.sitkFloat32)
    brain_mask = sitk.GetArrayFromImage(mask_img)
    volume_indices = brain_mask.astype(bool)
    shape = (vector_maps.shape[0], brain_mask.shape[0], brain_mask.shape[1],
             brain_mask.shape[2])
    volumes = np.zeros(shape)
    for i in range(vector_maps.shape[0]):
        volume = volumes[i, :, :, :]
        volume[volume_indices] = vector_maps[i, :]
        volumes[i, :, :, :] = volume
    volume_img = copyInfo_4DImage(
        sitk.GetImageFromArray(volumes, isVector=False), mask_img,
        sitk.ReadImage(ref_4d))
    return volume_img
Esempio n. 2
0
def resample_IC_file(in_file, ref_file, transforms=[], inverses=[]):
    # resampling the reference image to the dimension of the EPI
    import SimpleITK as sitk
    import os
    from rabies.utils import split_volumes, copyInfo_4DImage, exec_applyTransforms
    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'

    # Splitting bold file into lists of single volumes
    [volumes_list, num_volumes] = split_volumes(in_file, "bold_",
                                                sitk.sitkFloat32)

    warped_volumes = []
    for x in range(0, num_volumes):
        warped_vol_fname = os.path.abspath("deformed_volume" + str(x) +
                                           ".nii.gz")
        warped_volumes.append(warped_vol_fname)
        exec_applyTransforms(transforms=transforms,
                             inverses=inverses,
                             input_image=volumes_list[x],
                             ref_image=ref_file,
                             output_image=warped_vol_fname,
                             mask=False)

    sample_volume = sitk.ReadImage(warped_volumes[0])
    shape = sitk.GetArrayFromImage(sample_volume).shape
    combined = np.zeros((num_volumes, shape[0], shape[1], shape[2]))

    i = 0
    for file in warped_volumes:
        combined[i, :, :, :] = sitk.GetArrayFromImage(
            sitk.ReadImage(file))[:, :, :]
        i = i + 1
    if (i != num_volumes):
        raise ValueError("Error occured with Merge.")

    combined_image = sitk.GetImageFromArray(combined, isVector=False)

    # set metadata and affine for the newly constructed 4D image
    header_source = sitk.ReadImage(in_file)
    combined_image = copyInfo_4DImage(combined_image, sample_volume,
                                      header_source)
    sitk.WriteImage(combined_image, out_file)
    return out_file
Esempio n. 3
0
                tmppath+'/inputs/sub-token_bold.nii.gz')

resampled = resample_image_spacing(sitk.ReadImage(mask), spacing)
array = sitk.GetArrayFromImage(resampled)
array[array < 1] = 0
array[array > 1] = 1
binarized = sitk.GetImageFromArray(array, isVector=False)
binarized.CopyInformation(resampled)
sitk.WriteImage(binarized, tmppath+'/inputs/token_mask.nii.gz')
array[:, :, :6] = 0
binarized = sitk.GetImageFromArray(array, isVector=False)
binarized.CopyInformation(resampled)
sitk.WriteImage(binarized, tmppath+'/inputs/token_mask_half.nii.gz')


sitk.WriteImage(copyInfo_4DImage(sitk.ReadImage(tmppath+'/inputs/sub-token_bold.nii.gz'), sitk.ReadImage(tmppath
                + '/inputs/sub-token_T1w.nii.gz'), sitk.ReadImage(tmppath+'/inputs/sub-token_bold.nii.gz')), tmppath+'/inputs/sub-token_bold.nii.gz')

command = f"rabies --verbose 1 preprocess {tmppath}/inputs {tmppath}/outputs --anat_inho_cor_method disable --bold_inho_cor_method disable \
    --anat_template {tmppath}/inputs/sub-token_T1w.nii.gz --brain_mask {tmppath}/inputs/token_mask.nii.gz --WM_mask {tmppath}/inputs/token_mask.nii.gz --CSF_mask {tmppath}/inputs/token_mask.nii.gz --vascular_mask {tmppath}/inputs/token_mask.nii.gz --labels {tmppath}/inputs/token_mask.nii.gz \
    --coreg_script no_reg --atlas_reg_script no_reg --data_type int16 --bold_only --fast_commonspace --detect_dummy \
    --tpattern seq"
process = subprocess.run(
    command,
    check=True,
    shell=True,
    )

os.remove(f'{tmppath}/outputs/rabies_preprocess.pkl')
command = f"rabies --verbose 1 preprocess {tmppath}/inputs {tmppath}/outputs --anat_inho_cor_method disable --bold_inho_cor_method disable \
    --anat_template {tmppath}/inputs/sub-token_T1w.nii.gz --brain_mask {tmppath}/inputs/token_mask.nii.gz --WM_mask {tmppath}/inputs/token_mask_half.nii.gz --CSF_mask {tmppath}/inputs/token_mask_half.nii.gz --vascular_mask {tmppath}/inputs/token_mask_half.nii.gz --labels {tmppath}/inputs/token_mask.nii.gz \
    --coreg_script no_reg --atlas_reg_script no_reg --data_type int16 --HMC_option 0 --commonspace_masking --coreg_masking --brain_extraction"
Esempio n. 4
0
    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
Esempio n. 5
0
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