Exemplo n.º 1
0
 def _resample_slicewise(self, image, p_resample, type_img, image_ref=None):
     """
     Resample at a fixed resolution to make sure the cord always appears with similar scale, regardless of the native
     resolution of the image. Assumes SAL orientation.
     :param image: Image() to resample
     :param p_resample: float: Resampling resolution in mm
     :param type_img: {'im', 'seg'}: If im, interpolate using spline. If seg, interpolate using linear then binarize.
     :param image_ref: Destination Image() to resample image to.
     :return:
     """
     dict_interp = {'im': 'spline', 'seg': 'linear'}
     # Create nibabel object
     nii = Nifti1Image(image.data, image.hdr.get_best_affine())
     # If no reference image is provided, resample to specified resolution
     if image_ref is None:
         # Resample to px x p_resample x p_resample mm (orientation is SAL by convention in QC module)
         nii_r = resample_nib(nii, new_size=[image.dim[4], p_resample, p_resample], new_size_type='mm',
                              interpolation=dict_interp[type_img])
     # Otherwise, resampling to the space of the reference image
     else:
         # Create nibabel object for reference image
         nii_ref = Nifti1Image(image_ref.data, image_ref.hdr.get_best_affine())
         nii_r = resample_nib(nii, image_dest=nii_ref, interpolation=dict_interp[type_img])
     # If resampled image is a segmentation, binarize using threshold at 0.5
     if type_img == 'seg':
         img_r_data = (nii_r.get_data() > 0.5) * 1
     else:
         img_r_data = nii_r.get_data()
     # Create Image objects
     image_r = Image(img_r_data, hdr=nii_r.header, dim=nii_r.header.get_data_shape()). \
         change_orientation(image.orientation)
     return image_r
Exemplo n.º 2
0
def test_affines_save(image_orientation):
    """Check implementation of exporting affines to formats."""
    # Generate test transform
    img = loadimg(SOMEONES_ANATOMY)
    imgaff = img.affine

    if image_orientation == 'LAS':
        newaff = imgaff.copy()
        newaff[0, 0] *= -1.0
        newaff[0, 3] = imgaff.dot(np.hstack(
            (np.array(img.shape[:3]) - 1, 1.0)))[0]
        img = Nifti1Image(np.flip(img.get_fdata(), 0), newaff, img.header)
    elif image_orientation == 'LPS':
        newaff = imgaff.copy()
        newaff[0, 0] *= -1.0
        newaff[1, 1] *= -1.0
        newaff[:2,
               3] = imgaff.dot(np.hstack(
                   (np.array(img.shape[:3]) - 1, 1.0)))[:2]
        img = Nifti1Image(np.flip(np.flip(img.get_fdata(), 0), 1), newaff,
                          img.header)
    elif image_orientation == 'oblique':
        A = shape_zoom_affine(img.shape, img.header.get_zooms(), x_flip=False)
        R = from_matvec(euler2mat(x=0.09, y=0.001, z=0.001))
        newaff = R.dot(A)
        img = Nifti1Image(img.get_fdata(), newaff, img.header)
        img.header.set_qform(newaff, 1)
        img.header.set_sform(newaff, 1)

    T = from_matvec(euler2mat(x=0.9, y=0.001, z=0.001), [4.0, 2.0, -1.0])

    xfm = nbl.Affine(T)
    xfm.reference = img

    itk = nbl.load(os.path.join(data_path,
                                'affine-%s-itk.tfm' % image_orientation),
                   fmt='itk')
    fsl = np.loadtxt(
        os.path.join(data_path, 'affine-%s.fsl' % image_orientation))
    afni = np.loadtxt(
        os.path.join(data_path, 'affine-%s.afni' % image_orientation))

    with InTemporaryDirectory():
        xfm.to_filename('M.tfm', fmt='itk')
        xfm.to_filename('M.fsl', fmt='fsl')
        xfm.to_filename('M.afni', fmt='afni')

        nb_itk = nbl.load('M.tfm', fmt='itk')
        nb_fsl = np.loadtxt('M.fsl')
        nb_afni = np.loadtxt('M.afni')

    assert_equal(itk, nb_itk)
    assert_almost_equal(fsl, nb_fsl)
    assert_almost_equal(afni, nb_afni)


# Create version not aligned to canonical
Exemplo n.º 3
0
def test_smooth_image(caplog):
    # Test image smoothing
    data = np.arange(24).reshape((2, 3, 4))
    aff = np.diag([-4, 5, 6, 1])
    img = Nifti1Image(data, aff)
    # Zero smoothing is no-op
    out_img = smooth_image(img, 0)
    assert_array_equal(out_img.affine, img.affine)
    assert_array_equal(out_img.shape, img.shape)
    assert_array_equal(out_img.dataobj, data)
    # Isotropic smoothing
    sd = fwhm2sigma(np.true_divide(8, [4, 5, 6]))
    exp_out = spnd.gaussian_filter(data, sd, mode='nearest')
    assert_array_equal(smooth_image(img, 8).dataobj, exp_out)
    assert_array_equal(smooth_image(img, [8, 8, 8]).dataobj, exp_out)
    with pytest.raises(ValueError):
        smooth_image(img, [8, 8])
    # Not isotropic
    mixed_sd = fwhm2sigma(np.true_divide([8, 7, 6], [4, 5, 6]))
    exp_out = spnd.gaussian_filter(data, mixed_sd, mode='nearest')
    assert_array_equal(smooth_image(img, [8, 7, 6]).dataobj, exp_out)
    # In 2D
    img_2d = Nifti1Image(data[0], aff)
    exp_out = spnd.gaussian_filter(data[0], sd[:2], mode='nearest')
    assert_array_equal(smooth_image(img_2d, 8).dataobj, exp_out)
    assert_array_equal(smooth_image(img_2d, [8, 8]).dataobj, exp_out)
    with pytest.raises(ValueError):
        smooth_image(img_2d, [8, 8, 8])
    # Isotropic in 4D has zero for last dimension in scalar case
    data_4d = np.arange(24 * 5).reshape((2, 3, 4, 5))
    img_4d = Nifti1Image(data_4d, aff)
    exp_out = spnd.gaussian_filter(data_4d, list(sd) + [0], mode='nearest')
    assert_array_equal(smooth_image(img_4d, 8).dataobj, exp_out)
    # But raises error for vector case
    with pytest.raises(ValueError):
        smooth_image(img_4d, [8, 8, 8])
    # mode, cval
    exp_out = spnd.gaussian_filter(data, sd, mode='constant')
    assert_array_equal(smooth_image(img, 8, mode='constant').dataobj, exp_out)
    exp_out = spnd.gaussian_filter(data, sd, mode='constant', cval=99)
    assert_array_equal(
        smooth_image(img, 8, mode='constant', cval=99).dataobj, exp_out)
    # out_class
    img_ni1 = Nifti1Image(data, np.eye(4))
    img_ni2 = Nifti2Image(data, np.eye(4))
    # Default is Nifti1Image
    with caplog.at_level(
            logging.CRITICAL
    ):  # Here and below, suppress logs when changing classes
        assert smooth_image(img_ni2, 0).__class__ == Nifti1Image
    # Can be overridden
    with caplog.at_level(logging.CRITICAL):
        assert smooth_image(img_ni1, 0,
                            out_class=Nifti2Image).__class__ == Nifti2Image
    # None specifies out_class from input
    assert smooth_image(img_ni2, 0, out_class=None).__class__ == Nifti2Image
Exemplo n.º 4
0
def generate_average_density_map(data_dir, file_path_data, tract, space):
    '''Loads and averages the tract density maps in the file_paths list.
    Then saves averaged density map in data/temp folder so it can be sent in 
    a response later.
    '''
    data = np.zeros((len(file_path_data), 91, 109, 91), dtype=np.float32)
    for i in range(len(file_path_data)):
        subject_id = file_path_data[i][0]
        dataset_dir = file_path_data[i][1]
        method = file_path_data[i][2]
        data[i] = nib.load(
            file_path(data_dir, dataset_dir, tract.file_path, method,
                      subject_id, space, tract.code, 'nii.gz')).get_data()

    data[np.nonzero(data)] = 1  # binarize before averaging
    mean = np.mean(data, axis=0)

    # add the template affine and header to the averaged nii to ensure correct alignment in XTK library
    # maybe cache the template affine and header on startup so we don't need to do this load here?
    template = nib.load(data_dir + '/' + TEMPLATE_FILE_NAME)
    new_img = Nifti1Image(mean.astype(np.float32), template.affine,
                          template.header)
    temp_file_path = temp_file(data_dir, tract.code, '.nii.gz')
    nib.save(new_img, temp_file_path)
    return temp_file_path
Exemplo n.º 5
0
 def _resample(self, image, p_resample, type, image_ref=None):
     """
     Resample at a fixed resolution to make sure the cord always appears with similar scale, regardless of the native
     resolution of the image. Assumes SAL orientation.
     :param image: Image() to resample
     :param p_resample: float: Resampling resolution in mm
     :param type: {'im', 'seg'}: If im, interpolate using spline. If seg, interpolate using linear then binarize.
     :param image_ref: Destination Image() to resample image to.
     :return:
     """
     # If no reference image is provided, create nipy object and resample using resample_nipy()
     if image_ref is None:
         dict_interp = {'im': 'spline', 'seg': 'linear'}
         # Create nibabel object
         nii = Nifti1Image(image.data, image.hdr.get_best_affine())
         img = nifti2nipy(nii)
         # Resample to px x p_resample x p_resample mm (orientation is SAL by convention in QC module)
         img_r = resample_nipy(img, new_size=str(image.dim[4]) + 'x' + str(p_resample) + 'x' + str(p_resample),
                               new_size_type='mm', interpolation=dict_interp[type])
         # If segmentation, binarize using threshold at 0.5
         if type == 'seg':
             img_r_data = (img_r.get_data() > 0.5) * 1
         else:
             img_r_data = img_r.get_data()
         nii_r = nipy2nifti(img_r)
         # Create Image objects
         image_r = Image(img_r_data, hdr=nii_r.header, dim=nii_r.header.get_data_shape()). \
             change_orientation(image.orientation)
     # If resampling to reference image, use Image() built-in resampling function to ref image
     else:
         dict_interp = {'im': 3, 'seg': 0}
         image_r = image.interpolate_from_image(image_ref, interpolation_mode=dict_interp[type], border='nearest')
     return image_r
Exemplo n.º 6
0
def smooth_image_file(in_file, smooth_file, sigma=0):
    img = nii_io.readnii(in_file)
    img_data = img.get_data()
    smooth_img_data = smooth_image(img_data, sigma)
    smooth_img = Nifti1Image(smooth_img_data,
                             affine=img.get_affine(),
                             header=img.get_header())
    nii_io.writenii(smooth_file, smooth_img)
Exemplo n.º 7
0
def subject_averaged_MD(subject_ids_dataset_paths, data_dir):
    template = nib.load(data_dir + '/' + TEMPLATE_FILE_NAME)
    new_img = Nifti1Image(
        subject_averaged_map(subject_ids_dataset_paths, 'MD', data_dir),
        template.affine, template.header)
    file_path = temp_file(data_dir, 'MD', '.nii.gz')
    nib.save(new_img, file_path)
    return file_path
Exemplo n.º 8
0
def process_subject(
    input_files: str,
    peaks_file: str,
    subject_id: str,
    normalize: bool = False,
    wm: str = None,
    gm: str = None,
    csf: str = None,
    interface: str = None
) -> Tuple[np.ndarray, List, List, Dict, np.ndarray, np.ndarray]:

    affine = nib.load(input_files[0]).affine

    input_volumes = [nib.load(f).get_fdata() for f in input_files]
    for i, v in enumerate(input_volumes):
        if len(v.shape) == 3:
            input_volumes[i] = v[..., None]

    peaks_image = nib.load(peaks_file)

    wm_mask_image = None
    if wm:
        wm_mask_image = nib.load(wm)

    gm_mask_image = None
    if gm:
        gm_mask_image = nib.load(gm)

    csf_mask_image = None
    if csf:
        csf_mask_image = nib.load(csf)

    interface_mask_image = None
    if interface:
        interface_mask_image = nib.load(interface)

    if normalize:
        print('Normalizing signal volume')
        input_volume = normalize_data_volume(input_volumes[0])
    else:
        input_volume = input_volumes[0]

    inputs = np.concatenate([input_volume] + input_volumes[1:], axis=-1)

    # Save processed data
    input_image = Nifti1Image(inputs, affine)

    return (input_image, peaks_image, wm_mask_image, gm_mask_image,
            csf_mask_image, interface_mask_image)
Exemplo n.º 9
0
def _reorient_to_ras(img: Nifti1Image) -> Nifti1Image:
    '''
    Re-orient image to RAS

    Args:
        img: Image to re-orient to match ref image

    Returns:
        img re-oriented to RAS
    '''

    img = nimg.load_img(img)
    ras_ornt = nib.orientations.axcodes2ornt(('R', 'A', 'S'))
    img_ornt = nib.orientations.axcodes2ornt(
        nib.orientations.aff2axcodes(img.affine))
    img2ref = nib.orientations.ornt_transform(img_ornt, ras_ornt)
    return img.as_reoriented(img2ref)
Exemplo n.º 10
0
def jacobian_det_image(in_file, out_file, sigma=0):
    nii = nii_io.readnii(in_file)
    nii_data = nii.get_data()
    if len(nii_data.shape) != 4:
        raise ValueError(
            ' Expecting a 4D file containing vector fields. The dimensions of '
            + in_file + ' are ' + str(nii_data.shape) +
            '.\n')  # TODO: Change this to a custom exception in future
    v1 = nii_data[:, :, :, 0]
    v2 = nii_data[:, :, :, 1]
    v3 = nii_data[:, :, :, 2]
    detJ, J = jacobian(v1, v2, v3)

    detJ_smooth = smooth_image(detJ, sigma)
    detJ_smooth_img = Nifti1Image(detJ_smooth,
                                  affine=nii.get_affine(),
                                  header=nii.get_header())
    nii_io.writenii(out_file, detJ_smooth_img)
Exemplo n.º 11
0
def test_resample_to_output():
    # Test routine to sample iamges to output space
    # Image aligned to output axes - no-op
    data = np.arange(24).reshape((2, 3, 4))
    img = Nifti1Image(data, np.eye(4))
    # Check default resampling
    img2 = resample_to_output(img)
    assert_array_equal(img2.shape, (2, 3, 4))
    assert_array_equal(img2.affine, np.eye(4))
    assert_array_equal(img2.dataobj, data)
    # Check resampling with different voxel size specifications
    for vox_sizes in (None, 1, [1, 1, 1]):
        img2 = resample_to_output(img, vox_sizes)
        assert_array_equal(img2.shape, (2, 3, 4))
        assert_array_equal(img2.affine, np.eye(4))
        assert_array_equal(img2.dataobj, data)
    img2 = resample_to_output(img, vox_sizes)
    # Check 2D works
    img_2d = Nifti1Image(data[0], np.eye(4))
    for vox_sizes in (None, 1, (1, 1), (1, 1, 1)):
        img3 = resample_to_output(img_2d, vox_sizes)
        assert_array_equal(img3.shape, (3, 4, 1))
        assert_array_equal(img3.affine, np.eye(4))
        assert_array_equal(img3.dataobj, data[0][..., None])
    # Even 1D
    img_1d = Nifti1Image(data[0, 0], np.eye(4))
    img3 = resample_to_output(img_1d)
    assert_array_equal(img3.shape, (4, 1, 1))
    assert_array_equal(img3.affine, np.eye(4))
    assert_array_equal(img3.dataobj, data[0, 0][..., None, None])
    # But 4D does not
    img_4d = Nifti1Image(data.reshape(2, 3, 2, 2), np.eye(4))
    with pytest.raises(ValueError):
        resample_to_output(img_4d)
    # Run vox2vox_out tests, checking output shape, coordinate transform
    for in_shape, in_aff, vox, out_shape, out_aff in get_outspace_params():
        # Allow for expansion of image shape from < 3D
        in_n_dim = len(in_shape)
        if in_n_dim < 3:
            in_shape = in_shape + (1,) * (3 - in_n_dim)
            if not vox is None:
                vox = vox + (1,) * (3 - in_n_dim)
            assert len(out_shape) == in_n_dim
            out_shape = out_shape + (1,) * (3 - in_n_dim)
        img = Nifti1Image(np.ones(in_shape), in_aff)
        out_img = resample_to_output(img, vox)
        assert_all_in(in_shape, in_aff, out_img.shape, out_img.affine)
        assert out_img.shape == out_shape
        assert_almost_equal(out_img.affine, out_aff)
    # Check data is as expected with some transforms
    # Flip first axis
    out_img = resample_to_output(Nifti1Image(data, np.diag([-1, 1, 1, 1])))
    assert_array_equal(out_img.dataobj, np.flipud(data))
    # Subsample voxels
    out_img = resample_to_output(Nifti1Image(data, np.diag([4, 5, 6, 1])))
    exp_out = spnd.affine_transform(data,
                                    [1/4, 1/5, 1/6],
                                    output_shape = (5, 11, 19))
    assert_array_equal(out_img.dataobj, exp_out)
    # Unsubsample with voxel sizes
    out_img = resample_to_output(Nifti1Image(data, np.diag([4, 5, 6, 1])),
                                 [4, 5, 6])
    assert_array_equal(out_img.dataobj, data)
    # A rotation to test nearest, order, cval
    rot_3 = from_matvec(euler2mat(np.pi / 4), [0, 0, 0])
    rot_3_img = Nifti1Image(data, rot_3)
    out_img = resample_to_output(rot_3_img)
    exp_shape = (4, 4, 4)
    assert out_img.shape == exp_shape
    exp_aff = np.array([[1, 0, 0, -2 * np.cos(np.pi / 4)],
                        [0, 1, 0, 0],
                        [0, 0, 1, 0],
                        [0, 0, 0, 1]])
    assert_almost_equal(out_img.affine, exp_aff)
    rzs, trans = to_matvec(np.dot(npl.inv(rot_3), exp_aff))
    exp_out = spnd.affine_transform(data, rzs, trans, exp_shape)
    assert_almost_equal(out_img.dataobj, exp_out)
    # Order
    assert_almost_equal(
        resample_to_output(rot_3_img, order=0).dataobj,
        spnd.affine_transform(data, rzs, trans, exp_shape, order=0))
    # Cval
    assert_almost_equal(
        resample_to_output(rot_3_img, cval=99).dataobj,
        spnd.affine_transform(data, rzs, trans, exp_shape, cval=99))
    # Mode
    assert_almost_equal(
        resample_to_output(rot_3_img, mode='nearest').dataobj,
        spnd.affine_transform(data, rzs, trans, exp_shape, mode='nearest'))
    # out_class
    img_ni1 = Nifti2Image(data, np.eye(4))
    img_ni2 = Nifti2Image(data, np.eye(4))
    # Default is Nifti1Image
    assert resample_to_output(img_ni2).__class__ == Nifti1Image
    # Can be overriden
    assert resample_to_output(img_ni1, out_class=Nifti2Image).__class__ == Nifti2Image
    # None specifies out_class from input
    assert resample_to_output(img_ni2, out_class=None).__class__ == Nifti2Image
def plotGlassbrainSlices(niftipath, mnipath, ortho='z', nRows=2, nCuts=6,
                         threshpos=0, threshneg=0, figLayout='Both',
                         showLRannot=True, findOptimalCut=True,
                         imageType='svg'):
    """
    Creates nice glassbrain slice figures in the direction x, y and z
    """

    # Initiation of relevant parameters
    img = nb.load(niftipath)
    lineW = 2. / (nRows + int((figLayout == 'Brain' or figLayout == 'Both')))

    # Reduce 4D volume to 3D
    if len(img.shape) == 4:
        data4D = img.get_data()
        data4D = data4D.reshape(data4D.shape[:-1])
        img = Nifti1Image(data4D, img.get_affine())

    # Get voxel extend in all directions
    dirMin = np.dot(img.get_affine(), [0, 0, 0, 1])[:3]
    dirMax = np.dot(img.get_affine(),
                    np.array(img.shape).tolist() + [1])[:3]

    if findOptimalCut:
        # Find cuts automatically
        cut_coords = find_cut_slices(img, direction=ortho, n_cuts=nCuts)
    else:
        # Split orientation in x-equal parts
        cut_coords = getEqualSpacing(dirMin, dirMax, ortho, nCuts)

    # Split cuts according nRows
    cut_coords = [cut_coords[int(i * len(cut_coords) / np.float(nRows)):
                             int((i + 1) * len(cut_coords) / np.float(nRows))]
                  for i in range(nRows)]

    # Create Slices
    for i in range(nRows):

        # Create axes for plotting
        ax = plt.subplot(nRows + int((figLayout == 'Brain' or
                                      figLayout == 'Both')),
                         1, i + 1)

        # Plot the white background for all slices as a zeros value brain
        # (without it, the view focuses around the first area plotted)
        zerobrain = Nifti1Image(img.get_data() * 0, img.get_affine())
        brain = plot_roi(
            zerobrain, zerobrain, colorbar=False, cut_coords=cut_coords[i],
            display_mode=ortho, alpha=1, draw_cross=False, cmap=plt.cm.gray,
            black_bg=False, axes=ax, annotate=False)

        # Plot positive values
        posdata = np.copy(img.get_data())
        posdata[posdata <= threshpos] = 0.001  # = 0 crashes contour function
        posbrain = Nifti1Image(posdata, img.get_affine())
        brain.add_contours(
            posbrain, filled=False, cmap=plt.cm.hot, alpha=1, linewidths=lineW)

        # Plot negative values
        negdata = np.copy(img.get_data())
        negdata[negdata >= -threshneg] = 0.001  # = 0 crashes contour function
        negbrain = Nifti1Image(negdata, img.get_affine())
        brain.add_contours(
            negbrain, filled=False, cmap=plt.cm.winter, alpha=1,
            linewidths=lineW)

        # Plot outer MNI contours
        brain.add_contours(
            smooth_img(mnipath, 4), alpha=1, filled=False,
            levels=[100], linewidths=lineW, cmap=plt.cm.gray)

        # Plot inner MNI contours
        brain.add_contours(
            nb.load(mnipath), alpha=0.8, levels=[5000], linewidths=lineW,
            cmap=plt.cm.gray)

        # Add annotation if requested
        if figLayout == 'Both' or figLayout == 'Number':
            brain.annotate(left_right=showLRannot, size=int(12 * lineW))

    # Plot overview Brain at the bottom
    if figLayout == 'Brain' or figLayout == 'Both':

        # Create axes for overview brain
        ax = plt.subplot(nRows + 1, 1, nRows + 1)

        # Find overview view direction
        if ortho == 'z':
            direction = 'x'
        elif ortho == 'x':
            direction = 'z'
        elif ortho == 'y':
            direction = 'z'

        # Plot the white backgroundas a zeros value brain
        brain = plot_roi(
            zerobrain, zerobrain, colorbar=False, cut_coords=[0],
            display_mode=direction, alpha=1, draw_cross=False,
            cmap=plt.cm.gray, black_bg=False, axes=ax, annotate=False)

        # Plot positive values
        brain.add_contours(
            posbrain, filled=False, cmap=plt.cm.hot, alpha=1, linewidths=lineW)

        # Plot negative values
        brain.add_contours(
            negbrain, filled=False, cmap=plt.cm.winter, alpha=1,
            linewidths=lineW)

        # Plot outer MNI contours
        brain.add_contours(
            smooth_img(mnipath, 4), alpha=1, filled=False,
            levels=[100], linewidths=lineW, cmap=plt.cm.gray)

        # Plot inner MNI contours
        brain.add_contours(
            nb.load(mnipath), alpha=0.8, levels=[5000], linewidths=lineW,
            cmap=plt.cm.gray)

        # Plot the line indicating the cut
        for i in np.array(cut_coords).flatten():
            if ortho == 'z' or ortho == 'y':
                ax.plot([-100, 100], [i, i], 'k-', lw=lineW)
            elif ortho == 'x':
                ax.plot([i, i], [-100, 100], 'k-', lw=lineW)

        if ortho == 'z':
            ax.axis((-300.0, 300.0, dirMin[2], dirMax[2]))
        elif ortho == 'y':
            ax.axis((-300.0, 300.0, dirMin[1], dirMax[1]))
        elif ortho == 'x':
            stretcher = (nRows + 1) / 2.
            ax.axis((-300.0 * stretcher, 300.0 * stretcher, -100.0, 100.0))

        # Add annotation if requested
        if figLayout == 'Both' or figLayout == 'Number':
            brain.annotate(left_right=showLRannot, size=int(12 * lineW))

    # Get file prefix
    if niftipath.endswith('.nii'):
        filename = opb(niftipath)[:-4]
    elif niftipath.endswith('.nii.gz'):
        filename = opb(niftipath)[:-7]

    # Create output folder
    path2Figure = opj(os.path.split(os.path.realpath(niftipath))[0], 'figures')
    if not os.path.exists(opj(path2Figure)):
        os.makedirs(opj(path2Figure))

    # Save figure
    figname = '_'.join([filename, '%s-cut' % ortho])
    plt.savefig(opj(path2Figure, '%s.%s' % (figname, imageType)))
    plt.clf()
Exemplo n.º 13
0
import numpy as np
import pandas as pd
import nibabel as nib
from nibabel.nifti1 import Nifti1Image
from nilearn.input_data import NiftiLabelsMasker

epi = nib.load(snakemake.input.vol)
csf = nib.load(snakemake.input.csf)
wm = nib.load(snakemake.input.wm)

img = Nifti1Image(csf.get_fdata(), epi.affine, csf.header)
masker = NiftiLabelsMasker(labels_img=img, standardize=False)
time_series1 = masker.fit_transform(epi)

img = Nifti1Image(wm.get_fdata(), epi.affine, wm.header)
masker = NiftiLabelsMasker(labels_img=img, standardize=False)
time_series2 = masker.fit_transform(epi)

# Concatenate timeseries
df1 = pd.DataFrame({
    'CSF': time_series1[:, 0],
    'WhiteMatter': time_series2[:, 0]
})

# Load movement parameters (and their derivatives)
names = ['X', 'Y', 'Z', 'RotX', 'RotY', 'RotZ']
df2 = pd.read_csv(snakemake.input.movreg,
                  names=names,
                  header=None,
                  delim_whitespace=True)
Exemplo n.º 14
0
import numpy as np
import pandas as pd
import nibabel as nib
from nibabel.nifti1 import Nifti1Image

t1 = nib.load(snakemake.input.t1)
t1_vals = t1.get_fdata()

lh_cerebellum = nib.load(snakemake.input.lh_cerebellum).get_fdata()
rh_cerebellum = nib.load(snakemake.input.rh_cerebellum).get_fdata()

combined = np.zeros((t1.shape))
combined[(lh_cerebellum > 0) & (t1_vals < 2000)] = 8
combined[(rh_cerebellum > 0) & (t1_vals < 2000)] = 47

img = Nifti1Image(combined, t1.affine, t1.header)
nib.save(img, snakemake.output[0])
Exemplo n.º 15
0
def _get_input_names(data_dict):
    """Get names from dict
        Read in the data_dict to return the relevant file names. Will also
        add the default values if trDuration, isi, or burn_in haven't been set

    Parameters
    ----------

    data_dict : dict
        A dictionary to specify the parameters used for making data,
        specifying the following keys
        numTRs - int - Specify the number of time points
        multivariate_patterns - bool - Is the difference between conditions
        univariate (0) or multivariate (1)
        different_ROIs - bool - Are there different ROIs for each condition (
        1) or is it in the same ROI (0). If it is the same ROI and you are
        using univariate differences, the second condition will have a
        smaller evoked response than the other.
        event_duration - int - How long, in seconds, is each event
        scale_percentage - float - What is the percent signal change
        trDuration - float - How many seconds per volume
        save_dicom - bool - Save to data as a dicom (1) or numpy (0)
        save_realtime - bool - Do you want to save the data in real time (1)
        or as fast as possible (0)?
        isi - float - What is the time between each event (in seconds)
        burn_in - int - How long before the first event (in seconds)

    Returns
    ----------

    ROI_A_file : str
        Path to ROI for condition A

    ROI_B_file : str
        Path to ROI for condition B

    template_path : str
        Path to template file for data

    noise_dict_file : str
        Path to file containing parameters for noise simulation

    """

    # Load in the ROIs
    if data_dict.get('ROI_A_file') is None:
        vol = resource_stream(__name__, "sim_parameters/ROI_A.nii.gz").read()
        ROI_A_file = Nifti1Image.from_bytes(gzip.decompress(vol)).get_data()
    else:
        ROI_A_file = data_dict['ROI_A_file']

    if data_dict.get('ROI_B_file') is None:
        vol = resource_stream(__name__, "sim_parameters/ROI_B.nii.gz").read()
        ROI_B_file = Nifti1Image.from_bytes(gzip.decompress(vol)).get_data()
    else:
        ROI_B_file = data_dict['ROI_B_file']

    # Get the path to the template
    if data_dict.get('template_path') is None:
        vol = resource_stream(__name__,
                              "sim_parameters/sub_template.nii.gz").read()
        template_path = Nifti1Image.from_bytes(gzip.decompress(vol)).get_data()
    else:
        template_path = data_dict['template_path']

    # Load in the noise dict if supplied
    if data_dict.get('noise_dict_file') is None:
        file = resource_stream(__name__,
                               'sim_parameters/sub_noise_dict.txt').read()
        noise_dict_file = file
    else:
        noise_dict_file = data_dict['noise_dict_file']

    # Return the paths
    return ROI_A_file, ROI_B_file, template_path, noise_dict_file
Exemplo n.º 16
0
def save(data, filename):
    _save_nifti1(Nifti1Image(data, None), filename)
Exemplo n.º 17
0
import pytest
import os
import time
import glob
from pkg_resources import resource_stream
from typing import Dict
from nibabel.nifti1 import Nifti1Image
import gzip

# Test that it crashes without inputs
with pytest.raises(TypeError):
    gen.generate_data()  # type: ignore

data_dict = {}  # type: Dict
vol = resource_stream(gen.__name__, "sim_parameters/ROI_A.nii.gz").read()
data_dict['ROI_A_file'] = Nifti1Image.from_bytes(
    gzip.decompress(vol)).get_data()
vol = resource_stream(gen.__name__, "sim_parameters/ROI_B.nii.gz").read()
data_dict['ROI_B_file'] = Nifti1Image.from_bytes(
    gzip.decompress(vol)).get_data()
vol = resource_stream(gen.__name__,
                      "sim_parameters/sub_template.nii.gz").read()
data_dict['template_path'] = Nifti1Image.from_bytes(
    gzip.decompress(vol)).get_data()
noise_dict_file = resource_stream(gen.__name__,
                                  "sim_parameters/sub_noise_dict.txt").read()
data_dict['noise_dict_file'] = noise_dict_file
data_dict['numTRs'] = 30
data_dict['event_duration'] = 2
data_dict['scale_percentage'] = 1
data_dict['different_ROIs'] = True
data_dict['multivariate_pattern'] = False
Exemplo n.º 18
0
def rtss_to_nifti(input_rtstruct_dicom: str, input_structural_dicom: str,
                  output_rtss_nii: str, output_struct_nii: str,
                  exclude_labels: list, write_one_roi_per_file: bool):
    '''
    Convert RTSTRUCT and structural DICOM to a NIFTI mask.    
    '''

    #1. read the structural image.
    dicomFiles = next(os.walk(input_structural_dicom))[2]
    numberOfDicomImages = len(dicomFiles)
    dicomsSorted = sort_dcms_by_slice_pos(input_structural_dicom,
                                          dicomFiles,
                                          stop_before_pixels=False)
    ds_struct = dicomsSorted[0]['dataset']
    struct_voxels = voxel_array_from_sorted_dicoms(dicomsSorted)

    xPixelSize, yPixelSize = ds_struct.PixelSpacing[0], ds_struct.PixelSpacing[
        1]
    xyPixelSize = 0.5 * (xPixelSize + yPixelSize)
    #for now; remember to update with DistanceBetweenSlices
    zPixelSize = ds_struct.SliceThickness

    imwidth, imheight, imdepth = ds_struct.Rows, ds_struct.Columns, len(
        dicomsSorted)
    voxel_vol_mm3 = xPixelSize * yPixelSize * zPixelSize

    if not write_one_roi_per_file:
        rtss_voxels = [np.zeros([imwidth, imheight, imdepth], dtype=np.uint16)]
    else:
        rtss_voxels = []

    print('Voxel size: {} by {} by {} mm'.format(xPixelSize, yPixelSize,
                                                 zPixelSize))

    # Find position of first slice
    patientPosition = ds_struct.ImagePositionPatient
    patientStartingZ = dicomsSorted[0]['z']

    mm_vox_size = np.array([1. / xPixelSize, 1. / yPixelSize, 1. / zPixelSize])
    origin = np.array(
        [patientPosition[0], patientPosition[1], patientStartingZ])

    print('Patient position is ', patientPosition[:2])
    print('First slice at ', patientStartingZ)

    #2. read the RTSTRUCT.
    ds_rtss = pydicom.dcmread(input_rtstruct_dicom, stop_before_pixels=False)
    if [0x3006, 0x0020] not in ds_rtss:
        raise ValueError(
            'Cannot find (0x3006,0020) StructureSetROISequence tag in RTSS file'
        )

    structure_set_roi_sequence = ssrs = ds_rtss[(0x3006, 0x0020)]._value
    roi_contour_sequence = rcs = ds_rtss[(0x3006, 0x0039)]

    n = len(ssrs)
    print('Found {} structures'.format(n))

    roi_list = []
    current_region_code = 1
    roi_file_index = 0

    for ind in range(n):
        ss = ssrs[ind]
        roi_number = ss[(0x3006, 0x0022)].value
        roi_name = re.sub(r'\W+', '', ss[(0x3006, 0x0026)].value)
        print('ROI number {}, name {}'.format(roi_number, roi_name))

        if roi_name.lower() in exclude_labels:
            print('skipping structure', roi_name)
            continue

        roi_contour = None

        #now find the matching ROI contour.
        for rc in roi_contour_sequence:
            #print ('comparing',rc[0x3006, 0x0084]._value,'and', roi_number)
            if rc[0x3006, 0x0084]._value == roi_number:
                roi_contour = rc
                break

        if not roi_contour:
            print('WARNING: no matching roi contour sequence for this ROI')
            continue

        display_color = roi_contour[0x3006, 0x002a] if (
            0x3006, 0x002a) in roi_contour else None
        print('display color:', display_color)

        if (0x3006, 0x0040) in roi_contour:
            contour_sequence = roi_contour[0x3006, 0x0040]

        else:
            print('WARNING: no matching contour sequence for this ROI')
            continue
        nContours = len(contour_sequence._value)

        #write rasterized data to image array.
        nptsAcc = 0

        if write_one_roi_per_file:
            new_roi_voxels = np.zeros([imwidth, imheight, imdepth],
                                      dtype=np.uint16)
            rtss_voxels.append(new_roi_voxels)
            current_voxels = new_roi_voxels
        else:
            current_voxels = rtss_voxels[0]

        for k in range(nContours):
            contour = contour_sequence[k]
            npts = contour.NumberOfContourPoints
            nptsAcc += npts
            print('Contour {}, number of points: {}'.format(k + 1, npts))
            pts = contour.ContourData
            poly2d, z = pts2poly(pts, origin, mm_vox_size)

            imslice = current_region_code * get_rasterized_poly_slice(
                poly2d, imwidth, imheight)

            rtss_voxels[roi_file_index][:, :, z] = imslice

        #get region properties.
        try:
            p = measure.regionprops(
                (current_voxels == current_region_code).astype(int))[0]
            vol_mm3 = p.area * voxel_vol_mm3
        except:
            vol_mm3 = 0

        print('volume:', vol_mm3, 'mm3')

        v = display_color.value
        color = '0x{:02X}{:02X}{:02X}'.format(int(v[0]), int(v[1]), int(v[2]))

        if not write_one_roi_per_file:
            out_file = output_rtss_nii
        else:
            out_file = output_rtss_nii + '_' + roi_name

        roi_descriptor = dict(roi_number=roi_number,
                              roi_name=roi_name,
                              display_color=color,
                              num_contours=nContours,
                              points_in_all_contours=nptsAcc,
                              intensity_value=current_region_code,
                              out_file_root=out_file,
                              volume_mm3=vol_mm3)

        roi_list.append(roi_descriptor)

        #update appropriate counters
        if not write_one_roi_per_file:
            current_region_code += 1
        else:
            roi_file_index += 1

    #create and save nifti images.
    #flip axes to orient from DICOM (LPS) to RAS space

    flips = np.array([-1., -1., 1., 1.])
    nifti_affine = np.diag(
        np.array([xPixelSize, yPixelSize, zPixelSize, 1]) * flips)
    nifti_affine[:3, 3] = origin * flips[:-1]

    nifti_image_struct = Nifti1Image(struct_voxels, nifti_affine)

    if not write_one_roi_per_file:
        nifti_image_roi = Nifti1Image(rtss_voxels[0], nifti_affine)
        print('writing', output_rtss_nii)
        nibabel.nifti1.save(nifti_image_roi, output_rtss_nii)
    else:
        for i in range(len(rtss_voxels)):
            nifti_image_roi = Nifti1Image(rtss_voxels[i], nifti_affine)
            outfile = roi_list[i]['out_file_root']
            print('writing', outfile)
            nibabel.nifti1.save(nifti_image_roi, outfile)

    print('writing', output_rtss_nii + '.json')
    with open(output_rtss_nii + '.json', 'w') as fout:
        json.dump(roi_list, fout)

    print('writing', output_struct_nii)
    nibabel.nifti1.save(nifti_image_struct, output_struct_nii)
    print('done')
Exemplo n.º 19
0
def _mask_img(n):
    img = np.ones((1, 1, n))
    affine = np.eye(4)
    return Nifti1Image(img, affine=affine)
Exemplo n.º 20
0
def test_resample_from_to():
    # Test resampling from image to image / image space
    data = np.arange(24).reshape((2, 3, 4))
    affine = np.diag([-4, 5, 6, 1])
    img = Nifti1Image(data, affine)
    img.header['descrip'] = 'red shirt image'
    out = resample_from_to(img, img)
    assert_almost_equal(img.dataobj, out.dataobj)
    assert_array_equal(img.affine, out.affine)
    # Check resampling reverses effect of flipping axes
    # This will also test translations
    flip_ornt = np.array([[0, 1], [1, 1], [2, 1]])
    for axis in (0, 1, 2):
        ax_flip_ornt = flip_ornt.copy()
        ax_flip_ornt[axis, 1] = -1
        aff_flip_i = inv_ornt_aff(ax_flip_ornt, (2, 3, 4))
        flipped_img = Nifti1Image(flip_axis(data, axis),
                                  np.dot(affine, aff_flip_i))
        out = resample_from_to(flipped_img, ((2, 3, 4), affine))
        assert_almost_equal(img.dataobj, out.dataobj)
        assert_array_equal(img.affine, out.affine)
    # A translation of one voxel on each axis
    trans_aff = from_matvec(np.diag([-4, 5, 6]), [4, -5, -6])
    trans_img = Nifti1Image(data, trans_aff)
    out = resample_from_to(trans_img, img)
    exp_out = np.zeros_like(data)
    exp_out[:-1, :-1, :-1] = data[1:, 1:, 1:]
    assert_almost_equal(out.dataobj, exp_out)
    out = resample_from_to(img, trans_img)
    trans_exp_out = np.zeros_like(data)
    trans_exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1]
    assert_almost_equal(out.dataobj, trans_exp_out)
    # Test mode with translation of first axis only
    # Default 'constant' mode first
    trans1_aff = from_matvec(np.diag([-4, 5, 6]), [4, 0, 0])
    trans1_img = Nifti1Image(data, trans1_aff)
    out = resample_from_to(img, trans1_img)
    exp_out = np.zeros_like(data)
    exp_out[1:, :, :] = data[:-1, :, :]
    assert_almost_equal(out.dataobj, exp_out)
    # Then 'nearest' mode
    out = resample_from_to(img, trans1_img, mode='nearest')
    exp_out[0, :, :] = exp_out[1, :, :]
    assert_almost_equal(out.dataobj, exp_out)
    # Test order
    trans_p_25_aff = from_matvec(np.diag([-4, 5, 6]), [1, 0, 0])
    trans_p_25_img = Nifti1Image(data, trans_p_25_aff)
    # Suprising to me, but all points outside are set to 0, even with NN
    out = resample_from_to(img, trans_p_25_img, order=0)
    exp_out = np.zeros_like(data)
    exp_out[1:, :, :] = data[1, :, :]
    assert_almost_equal(out.dataobj, exp_out)
    out = resample_from_to(img, trans_p_25_img)
    exp_out = spnd.affine_transform(data, [1, 1, 1], [-0.25, 0, 0], order=3)
    assert_almost_equal(out.dataobj, exp_out)
    # Test cval
    out = resample_from_to(img, trans_img, cval=99)
    exp_out = np.zeros_like(data) + 99
    exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1]
    assert_almost_equal(out.dataobj, exp_out)
    # Out class
    out = resample_from_to(img, trans_img)
    assert out.__class__ == Nifti1Image
    # By default, type of from_img makes no difference
    n1_img = Nifti2Image(data, affine)
    out = resample_from_to(n1_img, trans_img)
    assert out.__class__ == Nifti1Image
    # Passed as keyword arg
    out = resample_from_to(img, trans_img, out_class=Nifti2Image)
    assert out.__class__ == Nifti2Image
    # If keyword arg is None, use type of from_img
    out = resample_from_to(n1_img, trans_img, out_class=None)
    assert out.__class__ == Nifti2Image
    # to_img type irrelevant in all cases
    n1_trans_img = Nifti2Image(data, trans_aff)
    out = resample_from_to(img, n1_trans_img, out_class=None)
    assert out.__class__ == Nifti1Image
    # From 2D to 3D, error, the fixed affine is not invertible
    img_2d = Nifti1Image(data[:, :, 0], affine)
    with pytest.raises(AffineError):
        resample_from_to(img_2d, img)
    # 3D to 2D, we don't need to invert the fixed matrix
    out = resample_from_to(img, img_2d)
    assert_array_equal(out.dataobj, data[:, :, 0])
    # Same for tuple as to_img imput
    out = resample_from_to(img, (img_2d.shape, img_2d.affine))
    assert_array_equal(out.dataobj, data[:, :, 0])
    # 4D input and output also OK
    data_4d = np.arange(24 * 5).reshape((2, 3, 4, 5))
    img_4d = Nifti1Image(data_4d, affine)
    out = resample_from_to(img_4d, img_4d)
    assert_almost_equal(data_4d, out.dataobj)
    assert_array_equal(img_4d.affine, out.affine)
    # Errors trying to match 3D to 4D
    with pytest.raises(ValueError):
        resample_from_to(img_4d, img)
    with pytest.raises(ValueError):
        resample_from_to(img, img_4d)
Exemplo n.º 21
0
import numpy as np
import pandas as pd
import nibabel as nib
from nibabel.nifti1 import Nifti1Image
from nilearn.input_data import NiftiLabelsMasker

atlas = nib.load(snakemake.input.rois)
labels = atlas.get_fdata()

# Relabel and extract timeseries for CSF and WM labels
img = np.zeros(labels.shape)
img[(labels == 4) | (labels == 43)] = 1  # CSF
img[labels > 5000] = 2  # WM

tmp = Nifti1Image(img, atlas.affine, atlas.header)
masker = NiftiLabelsMasker(labels_img=tmp, standardize=False)
time_series1 = masker.fit_transform(snakemake.input.vol)

# Then for whole brain (i.e., 'global')
brain = np.zeros(labels.shape)
brain[labels != 0] = 1

tmp = Nifti1Image(brain, atlas.affine, atlas.header)
masker = NiftiLabelsMasker(labels_img=tmp, standardize=False)
time_series2 = masker.fit_transform(snakemake.input.vol)

# Concatenate timeseries
df1 = pd.DataFrame({
    'CSF': time_series1[:, 0],
    'WhiteMatter': time_series1[:, 1],
    'GlobalSignal': time_series2[:, 0]
Exemplo n.º 22
0
# Prepare masker & Correct affine
template = load_mni152_template()
basc = datasets.fetch_atlas_basc_multiscale_2015(version='sym')['scale444']
orig_filename='F:/sim/template/restbaseline.nii.gz'
orig_img= image.load_img(orig_filename)
brainmask = load_mni152_brain_mask()
mem = Memory('nilearn_cache')
masker = NiftiLabelsMasker(labels_img = basc, mask_img = brainmask, 
                           memory=mem, memory_level=1, verbose=0,
                           detrend=False, standardize=False,  
                           high_pass=0.01,t_r=2,
                           resampling_target='labels')
masker.fit()

# Prep Classification
   
for s in np.arange(84,89):#range(suj):#
    for n in range(meas):
        sim_filename='F:/sim/sim_'+str(s+1)+'_'+ str(n+1)+ '.nii.gz'
        if os.path.exists(sim_filename): 
            sim_img = image.load_img(sim_filename)
            sim=sim_img.get_data()
            data_sim=Nifti1Image(sim,orig_img.affine)
            roi = masker.transform(data_sim)
            save_name= 'F:/sim/mni/roi_mni_'+str(s+1)+'_'+str(n+1)+'.npz'
            np.savez_compressed(save_name,roi=roi) 
            rest=roi[rest_mask]
            sio.savemat('F:/sim/rest/sim_'+str(s+1)+'_'+ str(n+1)+'_rest.mat', {'rest':rest})

        
Exemplo n.º 23
0
s4_file_path = 'TESTDATASETB004_MNI_'
s4_mmse = None


#### Subject tract metrics ####




#### Neuroimaging data ####

affine = np.eye(4)
nifti_dim = (91,109,91)

template_filepath = 'mgtrk_atlas_template.nii.gz'
template_nifti = Nifti1Image(np.ones(nifti_dim, dtype=np.int16), affine)

s1_MD = Nifti1Image(0.5*np.ones(nifti_dim, dtype=np.int16), affine)
s1_FA = Nifti1Image(0.5*np.ones(nifti_dim, dtype=np.int16), affine)

s3_MD = Nifti1Image(1.5*np.ones(nifti_dim, dtype=np.int16), affine)
s3_FA = Nifti1Image(1.5*np.ones(nifti_dim, dtype=np.int16), affine)

s1_t1 = Nifti1Image(np.ones(nifti_dim, dtype=np.int16), affine)
s3_t1 = Nifti1Image(np.ones(nifti_dim, dtype=np.int16), affine)

empty_nifti = Nifti1Image(np.zeros(nifti_dim, dtype=np.int16), affine)

lesion_filepath = 'lesion.nii.gz'
test_lesion = Nifti1Image(np.ones(nifti_dim, dtype=np.int16), affine)