Ejemplo n.º 1
0
def load_vols(vols):
    if isinstance(vols, list):
        return [load_vol(vol) if isinstance(vol, basestring)
                else vol for vol in vols]
    elif isinstance(vols, basestring):
        return nibabel.four_to_three(nibabel.load(vols))
    elif is_niimg(vols):
        return nibabel.four_to_three(vols)
    else:
        raise TypeError(type(vols))
Ejemplo n.º 2
0
    def prep_data(self, nifti1, bval1, bvec1, nifti2, bval2, bvec2):
        ''' Load the reconstructed image files and generate the files that TOPUP needs. '''
        ni1 = nb.load(nifti1)
        ni2 = nb.load(nifti2)
        phase_dim1 = ni1.get_header().get_dim_info()[1]
        phase_dim2 = ni2.get_header().get_dim_info()[1]

        bvals1 = np.loadtxt(bval1)
        bvals2 = np.loadtxt(bval2)
        bvecs1 = np.loadtxt(bvec1)
        bvecs2 = np.loadtxt(bvec2)

        nondwi1 = [im for i,im in enumerate(nb.four_to_three(ni1)) if bvals1[i]<10 and i<self.num_vols]
        nondwi2 = [im for i,im in enumerate(nb.four_to_three(ni2)) if bvals2[i]<10 and i<self.num_vols]

        b0 = nb.concat_images(nondwi1+nondwi2)
        # Topup requires an even number of slices
        if b0.shape[2]%2:
            d = b0.get_data()
            d = np.concatenate((d,np.zeros((d.shape[0],d.shape[1],1,d.shape[3]), dtype=d.dtype)),axis=2)
            b0 = nb.Nifti1Image(d, b0.get_affine())

        nb.save(b0, self.b0_file)
        with open(self.acq_file, 'w') as f:
            for i in xrange(len(nondwi1)):
                row = ['0','0','0',str(self.readout_time1),'\n']
                row[phase_dim1] = str(self.pe_dir1)
                f.write(' '.join(row))
            for i in xrange(len(nondwi2)):
                row = ['0','0','0',str(self.readout_time2),'\n']
                row[phase_dim2] = str(self.pe_dir2)
                f.write(' '.join(row))

        mux_ims1 = nb.four_to_three(ni1)[self.num_cal1:]
        mux_ims2 = nb.four_to_three(ni2)[self.num_cal2:]
        all_ims = nb.concat_images(mux_ims1 + mux_ims2)
        if all_ims.shape[2]%2:
            d = all_ims.get_data()
            d = np.concatenate((d,np.zeros((d.shape[0],d.shape[1],1,d.shape[3]), dtype=d.dtype)),axis=2)
            all_ims = nb.Nifti1Image(d, all_ims.get_affine())

        nb.save(all_ims, self.dwi_base+'.nii.gz')

        indices = ['1' for i in xrange(len(mux_ims1))] + [str(len(nondwi1)+1) for i in xrange(len(mux_ims2))]
        with open(self.index_file, 'w') as f:
            f.write(' '.join(indices))

        bvals = np.concatenate((bvals1[self.num_cal1:],bvals2[self.num_cal2:]), axis=0)
        bvecs = np.concatenate((bvecs1[:,self.num_cal1:],bvecs2[:,self.num_cal2:]), axis=1)
        with open(self.bval_file, 'w') as f:
            f.write(' '.join(['%0.1f' % value for value in bvals]))
        with open(self.bvec_file, 'w') as f:
            f.write(' '.join(['%0.4f' % value for value in bvecs[0,:]]) + '\n')
            f.write(' '.join(['%0.4f' % value for value in bvecs[1,:]]) + '\n')
            f.write(' '.join(['%0.4f' % value for value in bvecs[2,:]]) + '\n')
Ejemplo n.º 3
0
def test_save_vols():
    # setup
    n_scans = 10
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)
    threeD_vols = nibabel.four_to_three(film)

    # save vols manually
    film_filename = os.path.join(output_dir, "film.nii.gz")
    threeD_vols_filenames = [os.path.join(output_dir, "fMETHODS-%06i" % i) for i in range(len(threeD_vols))]

    # check saving seperate 3D vols
    for stuff in [film, threeD_vols]:
        if isinstance(stuff, list):
            basenames = [os.path.basename(x) for x in threeD_vols_filenames]
        else:
            basenames = os.path.basename(film_filename)
        for concat in [False, True]:
            for bn in [None, basenames]:
                saved_vols_filenames = save_vols(stuff, output_dir, ext=".nii.gz", concat=concat, basenames=bn)
                if not concat and isinstance(stuff, list):
                    assert_true(isinstance(saved_vols_filenames, list))
                    assert_equal(len(saved_vols_filenames), n_scans)
                    if not bn is None:
                        assert_equal(os.path.basename(saved_vols_filenames[7]), "fMETHODS-000007.nii.gz")
                else:
                    assert_true(isinstance(saved_vols_filenames, basestring))
                    assert_true(saved_vols_filenames.endswith(".nii.gz"), msg=saved_vols_filenames)
                    assert_true(is_4D(check_niimg_4d(saved_vols_filenames)))
Ejemplo n.º 4
0
def b0_average(in_dwi, in_bval, out_file=None):
    """
    A function that averages the *b0* volumes from a DWI dataset.

    .. warning:: *b0* should be already registered (head motion artifact should
      be corrected).

    """
    import numpy as np
    import nibabel as nb
    import os.path as op

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_dwi))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_avg_b0%s" % (fname, ext))

    imgs = np.array(nb.four_to_three(nb.load(in_dwi)))
    bval = np.loadtxt(in_bval)
    b0s = [im.get_data().astype(np.float32)
           for im in imgs[np.where(bval == 0)]]
    b0 = np.average(np.array(b0s), axis=0)

    hdr = imgs[0].get_header().copy()
    hdr.set_data_shape(b0.shape)
    hdr.set_xyzt_units('mm')
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file)
    return out_file
Ejemplo n.º 5
0
def b0_average(in_dwi, in_bval, max_b=10.0, out_file=None):
    """
    A function that averages the *b0* volumes from a DWI dataset.
    As current dMRI data are being acquired with all b-values > 0.0,
    the *lowb* volumes are selected by specifying the parameter max_b.

    .. warning:: *b0* should be already registered (head motion artifact should
      be corrected).

    """
    import numpy as np
    import nibabel as nb
    import os.path as op

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_dwi))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_avg_b0%s" % (fname, ext))

    imgs = np.array(nb.four_to_three(nb.load(in_dwi)))
    bval = np.loadtxt(in_bval)
    index = np.argwhere(bval <= max_b).flatten().tolist()

    b0s = [im.get_data().astype(np.float32)
           for im in imgs[index]]
    b0 = np.average(np.array(b0s), axis=0)

    hdr = imgs[0].get_header().copy()
    hdr.set_data_shape(b0.shape)
    hdr.set_xyzt_units('mm')
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file)
    return out_file
Ejemplo n.º 6
0
def time_avg(in_file, index=[0], out_file=None):
    """
    Average the input time-series, selecting the indices given in index

    .. warning:: time steps should be already registered (corrected for
      head motion artifacts).

    """
    import numpy as np
    import nibabel as nb
    import os.path as op

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_file))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_baseline%s" % (fname, ext))

    index = np.atleast_1d(index).tolist()

    imgs = np.array(nb.four_to_three(nb.load(in_file)))[index]
    if len(index) == 1:
        data = imgs[0].get_data().astype(np.float32)
    else:
        data = np.average(np.array([im.get_data().astype(np.float32)
                                    for im in imgs]), axis=0)

    hdr = imgs[0].get_header().copy()
    hdr.set_data_shape(data.shape)
    hdr.set_xyzt_units('mm')
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(data, imgs[0].get_affine(), hdr).to_filename(out_file)
    return out_file
Ejemplo n.º 7
0
def test_load_4D_img():
    # setup
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # try loading from 4D niimg
    film = create_random_image(n_scans=10)
    loaded_4D_img = load_4D_img(film)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from 4D image file
    film = create_random_image(n_scans=10)
    saved_img_filename = os.path.join(output_dir, "4D.nii.gz")
    nibabel.save(film, saved_img_filename)
    loaded_4D_img = load_4D_img(saved_img_filename)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from list of 3D niimgs
    film = create_random_image(n_scans=10)
    loaded_4D_img = load_4D_img(nibabel.four_to_three(film))
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from list of 3D image files
    film = create_random_image(n_scans=10)
    saved_vols_filenames = save_vols(film,
                                     output_dir,
                                     ext='.nii.gz',
                                     )
    loaded_4D_img = load_4D_img(saved_vols_filenames)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)
Ejemplo n.º 8
0
    def _run_interface(self, runtime):
        mask_imgs = [nb.load(fname) for fname in self.inputs.label_files]
        if len(mask_imgs) == 1:
            mask_imgs = nb.four_to_three(mask_imgs[0])

        masks = [mask_img.get_data().astype(np.bool) for mask_img in mask_imgs]

        n_masks = len(masks)

        if n_masks != len(self.inputs.class_labels):
            raise ValueError("Number of masks must match number of labels")

        img = nb.load(self.inputs.in_file)

        series = np.zeros((img.shape[3], n_masks))

        data = img.get_data()
        for j in range(n_masks):
            series[:, j] = data[masks[j], :].mean(axis=0)

        output = np.vstack((self.inputs.class_labels, series.astype(str)))
        self._results['out_file'] = os.path.join(runtime.cwd,
                                                 self.inputs.out_file)
        np.savetxt(
            self._results['out_file'], output, fmt=b'%s', delimiter='\t')

        return runtime
Ejemplo n.º 9
0
def read_niftis(file_lists):
    """
    Read niftis.

    Parameters
    ----------
    file_lists: list of list of paths.
        Each list of file paths is a unique class.

    Returns
    -------
    data, labels: tuple of array-like and list
        The data and corresponding labels
    """

    data0 = load_image(file_lists[0][0]).get_data()
    if len(data0.shape) == 3:
        x, y, z = data0.shape
        t = 1
    elif len(data0.shape) == 4:
        x, y, z, t = data0.shape
    else:
        raise ValueError("Cannot parse data with dimensions %r" % data0.shape)

    dt = (sum(len(fl) for fl in file_lists)) * t
    data = np.zeros((dt, x, y, z))

    labels = [[i] * (len(fl) * t) for i, fl in enumerate(file_lists)]
    labels = [item for sublist in labels for item in sublist]

    for i, fl in enumerate(file_lists):
        assert len([j for j in labels if j == i]) == len(fl) * t

    flattened_list = [item for sublist in file_lists for item in sublist]
    for i, f in enumerate(flattened_list):
        logger.info("Loading subject from file: %s%s" % (f, '' * 30))

        nifti = load_image(f)
        subject_data = nifti.get_data()

        if len(subject_data.shape) == 3:
            data[i] = subject_data
        elif len(subject_data.shape) == 4:
            data[i * t: (i + 1) * t] = subject_data.transpose((3, 0, 1, 2))
        else:
            raise ValueError("Cannot parse subject data with dimensions %r"
                             % subject_data.shape)

    logger.info("\rLoading subject from file: %s\n" % ('DONE' + " "*30))
    if data.shape[0] != len(labels):
        raise ValueError("Data and labels have different number of samples.")

    base_file = flattened_list[0]
    # Use nibabel in case we need to convert from 4d to 3d
    base = nib.load(base_file)
    if len(base.shape) == 4:
        base = nib.four_to_three(base)[0]

    return data, labels, base
Ejemplo n.º 10
0
    def _run_interface(self, runtime):
        if not self._have_nipy:
            raise RuntimeError('nipy is not installed')

        from nipy.algorithms.registration.histogram_registration import HistogramRegistration
        from nipy.algorithms.registration.affine import Affine

        vol1_nii = nb.load(self.inputs.volume1)
        vol2_nii = nb.load(self.inputs.volume2)

        dims = vol1_nii.get_data().ndim

        if dims == 3 or dims == 2:
            vols1 = [vol1_nii]
            vols2 = [vol2_nii]
        if dims == 4:
            vols1 = nb.four_to_three(vol1_nii)
            vols2 = nb.four_to_three(vol2_nii)

        if dims < 2 or dims > 4:
            raise RuntimeError('Image dimensions not supported (detected %dD file)' % dims)

        if isdefined(self.inputs.mask1):
            mask1 = nb.load(self.inputs.mask1).get_data() == 1
        else:
            mask1 = None

        if isdefined(self.inputs.mask2):
            mask2 = nb.load(self.inputs.mask2).get_data() == 1
        else:
            mask2 = None

        self._similarity = []

        for ts1, ts2 in zip(vols1, vols2):
            histreg = HistogramRegistration(from_img=ts1,
                                            to_img=ts2,
                                            similarity=self.inputs.metric,
                                            from_mask=mask1,
                                            to_mask=mask2)
            self._similarity.append(histreg.eval(Affine()))

        return runtime
Ejemplo n.º 11
0
def test_load_specific_vol():
    # setup
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    n_scans = 23

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)

    # test loading vol from nibabel image object
    for t in xrange(n_scans):
        _vol, _n_scans = load_specific_vol(film, t)
        assert_equal(_n_scans, n_scans)
        assert_true(isinstance(_vol, type(film)))
        assert_equal(_vol.shape, film.shape[:-1])
        numpy.testing.assert_array_equal(_vol.get_data(),
                                         film.get_data()[..., t])

    # test loading vol from a single 4D filename
    for ext in IMAGE_EXTENSIONS:
        for film_filename_type in ['str', 'list']:
            if film_filename_type == 'str':
                # save film as single filename with extension ext
                film_filename = os.path.join(output_dir, "4D%s" % ext)
                nibabel.save(film, film_filename)
            else:
                # save film as multiple filenames (3D vols), with ext extension
                vols = nibabel.four_to_three(film)
                film_filename = []
                for t, vol in zip(xrange(n_scans), vols):
                    vol_filename = os.path.join(output_dir,
                                                "vol_%i%s" % (t, ext))
                    nibabel.save(vol, vol_filename)
                    film_filename.append(vol_filename)

            # test loading proper
            for t in xrange(n_scans):
                # note that .img loads as Nifti1Pair, not Nifti1Image
                vol_type = nibabel.Nifti1Pair if ext == '.img' else \
                    nibabel.Nifti1Image

                # load specific 3D vol from 4D film by filename
                _vol, _n_scans = load_specific_vol(film_filename, t)
                assert_equal(_n_scans, n_scans)
                assert_true(isinstance(_vol, vol_type))
                assert_equal(_vol.shape, film.shape[:-1])
                numpy.testing.assert_array_equal(_vol.get_data(),
                                              film.get_data()[..., t])
Ejemplo n.º 12
0
def test_do_3Dto4D_merge():
    # setup
    n_scans = 10
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)
    threeD_vols = nibabel.four_to_three(film)

    _film = do_3Dto4D_merge(threeD_vols)

    assert_equal(_film.shape, film.shape)

    save_vols(threeD_vols, output_dir, ext='.nii.gz')
def split_warp_volumes_fn(in_file):
    from nipype import logging
    from nipype.utils.filemanip import split_filename
    import nibabel as nb
    import os.path as op
    iflogger = logging.getLogger('interface')
    iflogger.info(in_file)
    path, name, ext = split_filename(in_file)
    image = nb.load(in_file)
    x_img, y_img, z_img = nb.four_to_three(image)
    x = op.abspath(name + '_x' + ".nii.gz")
    y = op.abspath(name + '_y' + ".nii.gz")
    z = op.abspath(name + '_z' + ".nii.gz")
    nb.save(x_img, x)
    nb.save(y_img, y)
    nb.save(z_img, z)
    return x, y, z
Ejemplo n.º 14
0
    def _run_interface(self, runtime):
        from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel
        from dipy.data import get_sphere
        # import marshal as pickle
        import pickle as pickle
        import gzip

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.get_affine()

        if isdefined(self.inputs.in_mask):
            msk = nb.load(self.inputs.in_mask).get_data()
        else:
            msk = np.ones(imref.get_shape())

        data = img.get_data().astype(np.float32)
        hdr = imref.get_header().copy()

        gtab = self._get_gradient_table()
        resp_file = np.loadtxt(self.inputs.response)

        response = (np.array(resp_file[0:3]), resp_file[-1])
        ratio = response[0][1] / response[0][0]

        if abs(ratio - 0.2) > 0.1:
            IFLOGGER.warn(('Estimated response is not prolate enough. '
                           'Ratio=%0.3f.') % ratio)

        csd_model = ConstrainedSphericalDeconvModel(
            gtab, response, sh_order=self.inputs.sh_order)

        IFLOGGER.info('Fitting CSD model')
        csd_fit = csd_model.fit(data, msk)

        f = gzip.open(self._gen_filename('csdmodel', ext='.pklz'), 'wb')
        pickle.dump(csd_model, f, -1)
        f.close()

        if self.inputs.save_fods:
            sphere = get_sphere('symmetric724')
            fods = csd_fit.odf(sphere)
            nb.Nifti1Image(fods.astype(np.float32), img.get_affine(),
                           None).to_filename(self._gen_filename('fods'))

        return runtime
Ejemplo n.º 15
0
    def _run_interface(self, runtime):
        from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel
        from dipy.data import get_sphere
        # import marshal as pickle
        import cPickle as pickle
        import gzip

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.get_affine()

        if isdefined(self.inputs.in_mask):
            msk = nb.load(self.inputs.in_mask).get_data()
        else:
            msk = np.ones(imref.get_shape())

        data = img.get_data().astype(np.float32)
        hdr = imref.get_header().copy()

        gtab = self._get_gradient_table()
        resp_file = np.loadtxt(self.inputs.response)

        response = (np.array(resp_file[0:3]), resp_file[-1])
        ratio = response[0][1] / response[0][0]

        if abs(ratio - 0.2) > 0.1:
            IFLOGGER.warn(('Estimated response is not prolate enough. '
                           'Ratio=%0.3f.') % ratio)

        csd_model = ConstrainedSphericalDeconvModel(
            gtab, response, sh_order=self.inputs.sh_order)

        IFLOGGER.info('Fitting CSD model')
        csd_fit = csd_model.fit(data, msk)

        f = gzip.open(self._gen_filename('csdmodel', ext='.pklz'), 'wb')
        pickle.dump(csd_model, f, -1)
        f.close()

        if self.inputs.save_fods:
            sphere = get_sphere('symmetric724')
            fods = csd_fit.odf(sphere)
            nb.Nifti1Image(fods.astype(np.float32), img.get_affine(),
                           None).to_filename(self._gen_filename('fods'))

        return runtime
Ejemplo n.º 16
0
def smooth_image(img, fwhm, **kwargs):
    """Function wrapper LinearFilter class. Spatially smoothens img with
    kernel of size fwhm.

    Parameters
    ----------
    img: ``ni.Nifti1Image``
        image to be smoothen
    fwhm: 1D array like of size as big as there are spatial dimensions
    in the image
        FWHM of smoothing kernel
    **kwargs: dict-like
        key-word arguments passed to LinearFilter constructor.

    Returns
    -------
    Smoothened image, same type and size as the input img.

    """

    if isinstance(img, basestring):
        img = ni.load(img)
    elif isinstance(img, tuple):
        assert len(img) == 2
        return smooth_image(ni.Nifti1Image(img[0], img[1]), fwhm, **kwargs)
    elif isinstance(img, list):
        return [smooth_image(x, fwhm, **kwargs) for x in img]
    else:
        assert is_niimg(img)

    if len(img.shape) == 4:
        return ni.concat_images(
            [smooth_image(vol, fwhm, **kwargs)
             for vol in ni.four_to_three(img)])
    else:
        assert len(img.shape) == 3

        smoothing_kernel = LinearFilter(
            img.get_affine(),
            img.shape,
            fwhm=fwhm,
            **kwargs)

        return ni.Nifti1Image(smoothing_kernel.smooth(img.get_data(),
                                                      clean=True),
                              img.get_affine())
Ejemplo n.º 17
0
def test_save_vols():
    # setup
    n_scans = 10
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)
    threeD_vols = nibabel.four_to_three(film)

    # save vols manually
    film_filename = os.path.join(output_dir, 'film.nii.gz')
    threeD_vols_filenames = [os.path.join(output_dir, 'fMETHODS-%06i' % i)
                             for i in range(len(threeD_vols))]

    # check saving seperate 3D vols
    for stuff in [film, threeD_vols]:
        if isinstance(stuff, list):
            basenames = [os.path.basename(x)
                         for x in threeD_vols_filenames]
        else:
            basenames = os.path.basename(film_filename)
        for concat in [False, True]:
            for bn in [None, basenames]:
                saved_vols_filenames = save_vols(stuff,
                                                 output_dir,
                                                 ext='.nii.gz',
                                                 concat=concat,
                                                 basenames=bn
                                                 )
                if not concat and isinstance(stuff, list):
                    assert_true(isinstance(
                        saved_vols_filenames, list))
                    assert_equal(len(saved_vols_filenames),
                                 n_scans)
                    if not bn is None:
                        assert_equal(os.path.basename(saved_vols_filenames[7]),
                                     'fMETHODS-000007.nii.gz')
                else:
                    assert_true(isinstance(saved_vols_filenames, basestring))
                    assert_true(saved_vols_filenames.endswith('.nii.gz'),
                                msg=saved_vols_filenames)
                    assert_true(is_4D(check_niimg_4d(
                                saved_vols_filenames)))
Ejemplo n.º 18
0
    def _run_interface(self, runtime):
        img = nb.load(self.inputs.in_file)
        mask_imgs = [nb.load(fname) for fname in self.inputs.label_files]
        if len(mask_imgs) == 1 and len(mask_imgs[0].shape) == 4:
            mask_imgs = nb.four_to_three(mask_imgs[0])
        # This check assumes all input masks have same dimensions
        if img.shape[:3] != mask_imgs[0].shape[:3]:
            raise NotImplementedError(
                "Input image and mask should be of "
                "same dimensions before running SignalExtraction")
        # Load the mask.
        # If mask is a list, each mask is treated as its own ROI/parcel
        # If mask is a 3D, each integer is treated as its own ROI/parcel
        if len(mask_imgs) > 1:
            masks = [
                mask_img.get_data() >= self.inputs.prob_thres
                for mask_img in mask_imgs
            ]
        else:
            labelsmap = mask_imgs[0].get_data()
            labels = np.unique(labelsmap)
            labels = labels[labels != 0]
            masks = [labelsmap == l for l in labels]

        if len(masks) != len(self.inputs.class_labels):
            raise ValueError("Number of masks must match number of labels")

        series = np.zeros((img.shape[3], len(masks)))
        metadata = {}
        data = img.get_data()
        for j, (mask, label) in enumerate(zip(masks,
                                              self.inputs.class_labels)):
            series[:, j] = data[mask, :].mean(axis=0)
            metadata[label] = {'Method': 'Mean'}

        output = np.vstack((self.inputs.class_labels, series.astype(str)))
        self._results['out_file'] = os.path.join(runtime.cwd,
                                                 self.inputs.out_file)
        self._results['metadata'] = metadata
        np.savetxt(self._results['out_file'],
                   output,
                   fmt=b'%s',
                   delimiter='\t')

        return runtime
Ejemplo n.º 19
0
def smooth_image(img, fwhm, **kwargs):
    """Function wrapper LinearFilter class. Spatially smoothens img with
    kernel of size fwhm.

    Parameters
    ----------
    img: ``ni.Nifti1Image``
        image to be smoothen
    fwhm: 1D array like of size as big as there are spatial dimensions
    in the image
        FWHM of smoothing kernel
    **kwargs: dict-like
        key-word arguments passed to LinearFilter constructor.

    Returns
    -------
    Smoothened image, same type and size as the input img.

    """

    if isinstance(img, basestring):
        img = ni.load(img)
    elif isinstance(img, tuple):
        assert len(img) == 2
        return smooth_image(ni.Nifti1Image(img[0], img[1]), fwhm, **kwargs)
    elif isinstance(img, list):
        return [smooth_image(x, fwhm, **kwargs) for x in img]
    else:
        assert is_niimg(img)

    if len(img.shape) == 4:
        return ni.concat_images([
            smooth_image(vol, fwhm, **kwargs) for vol in ni.four_to_three(img)
        ])
    else:
        assert len(img.shape) == 3

        smoothing_kernel = LinearFilter(img.get_affine(),
                                        img.shape,
                                        fwhm=fwhm,
                                        **kwargs)

        return ni.Nifti1Image(
            smoothing_kernel.smooth(img.get_data(), clean=True),
            img.get_affine())
Ejemplo n.º 20
0
def _split_epi_lists(in_files, pe_dir, max_trs=50):
    """
    Split input EPIs and generate an output list of PEs.

    Inputs
    ------
    in_files : list of ``BIDSFile``s
        The EPI images that will be pooled into field estimation.
    pe_dir : str
        The phase-encoding direction of the IntendedFor EPI scan.
    max_trs : int
        Index of frame after which all volumes will be discarded
        from the input EPI images.

    """
    from os import path as op
    import nibabel as nb

    matched_pe = []
    opposed_pe = []

    for i, (epi_path, epi_pe) in enumerate(in_files):
        if epi_pe[0] == pe_dir[0]:
            img = nb.load(epi_path)
            if len(img.shape) == 3:
                splitnii = [img]
            else:
                splitnii = nb.four_to_three(img.slicer[:, :, :, :max_trs])

            for j, nii in enumerate(splitnii):
                out_name = op.abspath('dir-%s_tstep-%03d_pe-%03d.nii.gz' %
                                      (epi_pe, i, j))
                nii.to_filename(out_name)

                if epi_pe == pe_dir:
                    matched_pe.append(out_name)
                else:
                    opposed_pe.append(out_name)

    if matched_pe:
        return [opposed_pe, matched_pe]

    return [opposed_pe]
Ejemplo n.º 21
0
def load_specific_vol(vols, t, strict=False):
    """
    Utility function for loading specific volume on demand.

    Parameters
    ----------
    vols: string(s) or nibabel image object(s)
        input volumes or single 4D film
    t: int
        index of requested volume in the film

    """

    assert t >= 0

    if isinstance(vols, list):
        n_scans = len(vols)
        vol = load_vol(vols[t])
    elif is_niimg(vols) or isinstance(vols, basestring):
        _vols = nibabel.load(vols) if isinstance(vols, basestring) else vols
        if len(_vols.shape) != 4:
            if strict:
                raise ValueError(
                    "Expecting 4D image, got %iD" % len(_vols.shape))
            else:
                return _vols, 1

        n_scans = _vols.shape[-1]
        vol = nibabel.four_to_three(_vols)[t]
    else:  # unhandled type
        raise TypeError(
            ("vols must be string, image object, or list of such; "
             "got %s" % type(vols)))

    # delete trivial dimension
    if len(vol.shape) == 4:
        vol = nibabel.Nifti1Image(vol.get_data()[..., ..., ..., 0],
                                  vol.get_affine())

    assert is_niimg(vol)
    assert is_3D(vol)

    return vol, n_scans
Ejemplo n.º 22
0
 def normalization_2_common_space(self):
     print('normalization')
     for (input_nii_file,output_nii_file) in zip(self.input_nii, self.normalized_nii):
         print('run %s' % input_nii_file)
         print('generate %s' % output_nii_file)
         if os.path.exists(output_nii_file): continue
         dir_name = os.path.dirname(output_nii_file)
         if not os.path.exists(dir_name): os.makedirs(dir_name)
         mni_nii_file = self.get_mni152_nii_file(input_nii_file)
         nib_img = nib.load(input_nii_file)
         if len(nib_img.shape) > 3:
             nib_3d_imgs = nib.four_to_three(nib_img)
         else:
             nib_3d_imgs = [nib_img]
         dyn_3d_nib_files = []
         dyn_3d_nib_in_root = tempfile.mkdtemp()
         for nib_3d_img in nib_3d_imgs:
             nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz')
             nib_3d_img.to_filename(nib_3d_img_file)
             dyn_3d_nib_files.append(nib_3d_img_file)
         dyn_3d_nib_out_root = tempfile.mkdtemp()
         dyn_3d_nib_out_files = []
         for dyn_3d_nib_file in dyn_3d_nib_files:
             dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz')
             devnull = open(os.devnull, 'w')
             subprocess.call(['flirt',
                              '-in', dyn_3d_nib_file,
                              '-out', dyn_3d_nib_out_file,
                              '-ref', mni_nii_file,
                              '-bins', '256',
                              '-dof', '12'],stdout=devnull, stderr=subprocess.STDOUT)
             dyn_3d_nib_out_files.append(dyn_3d_nib_out_file)
         nib_3d_imgs = []
         for dyn_3d_nib_out_file in dyn_3d_nib_out_files:
             nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file))
         if len(nib_3d_imgs) > 1:
             nib_4d_img = nib.concat_images(nib_3d_imgs)
             nib_4d_img.to_filename(output_nii_file)
         else:
             nib_3d_imgs[0].to_filename(output_nii_file)
         if os.path.isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root)
         if os.path.isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root)
     return
Ejemplo n.º 23
0
    def _run_interface(self, runtime):
        in_file = self.inputs.in_file
        img = nb.load(in_file)
        extra_dims = tuple(dim for dim in img.shape[3:] if dim > 1) or (1, )
        if len(extra_dims) != 1:
            raise ValueError(
                f"Invalid shape {'x'.join(str(s) for s in img.shape)}")
        img = img.__class__(img.dataobj.reshape(img.shape[:3] + extra_dims),
                            img.affine, img.header)

        self._results["out_files"] = []
        for i, img_3d in enumerate(nb.four_to_three(img)):
            out_file = fname_presuffix(in_file,
                                       suffix=f"_idx-{i:03}",
                                       newpath=runtime.cwd)
            img_3d.to_filename(out_file)
            self._results["out_files"].append(out_file)

        return runtime
def test_transform():
    # setup
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    film = nibabel.Nifti1Image(np.random.rand(11, 13, 17, 19),
                               np.eye(4))
    threeD_vols = nibabel.four_to_three(film)

    # filenames
    film_filename = os.path.join(output_dir, 'film.nii.gz')
    threeD_vols_filenames = [os.path.join(output_dir, 'fMETHODS-%06i' % i)
                             for i in xrange(len(threeD_vols))]

    for stuff in [film, threeD_vols]:
        for as_files in [False, True]:
            if as_files:
                if isinstance(stuff, list):
                    basenames = [os.path.basename(x)
                                 for x in threeD_vols_filenames]
                else:
                    basenames = os.path.basename(film_filename)
                stuff = save_vols(stuff, output_dir, basenames=basenames)

            fmristc = fMRISTC().fit(raw_data=stuff)

            output = fmristc.transform(output_dir=output_dir)

            # test output type, shape, etc.
            if isinstance(stuff, list):
                nose.tools.assert_true(isinstance(
                        output, list))
                nose.tools.assert_equal(len(output),
                                        film.shape[-1])

                if as_files:
                    nose.tools.assert_equal(os.path.basename(output[7]),
                                            'afMETHODS-000007.nii.gz')
            else:
                if as_files:
                    nose.tools.assert_equal(os.path.basename(output),
                                            'afilm.nii.gz')                    
Ejemplo n.º 25
0
def estimate_motion(nifti_image):
    # BEGIN STDOUT SUPRESSION
    actualstdout = sys.stdout
    sys.stdout = open(os.devnull,'w')
    # We want to use the middle time point as the reference. But the algorithm does't allow that, so fake it.
    ref_vol = nifti_image.shape[3]/2 + 1
    ims = nb.four_to_three(nifti_image)
    reg = Realign4d(nb.concat_images([ims[ref_vol]] + ims)) # in the next release, we'll need to add tr=1.

    reg.estimate(loops=3) # default: loops=5
    aligned = reg.resample(0)[:,:,:,1:]
    sys.stdout = actualstdout
    # END STDOUT SUPRESSION
    abs_disp = []
    rel_disp = []
    transrot = []
    prev_T = None
    # skip the first one, since it's the reference volume
    for T in reg._transforms[0][1:]:
        # get the full affine for this volume by pre-multiplying by the reference affine
        #mc_affine = np.dot(ni.get_affine(), T.as_affine())
        transrot.append(T.translation.tolist()+T.rotation.tolist())
        # Compute the mean displacement
        # See http://www.fmrib.ox.ac.uk/analysis/techrep/tr99mj1/tr99mj1/node5.html
        # radius of the spherical head assumption (in mm):
        R = 80.
        # The center of the volume. Assume 0,0,0 in world coordinates.
        # Note: it might be better to use the center of mass of the brain mask.
        xc = np.matrix((0,0,0)).T
        T_error = T.as_affine() - np.eye(4)
        A = np.matrix(T_error[0:3,0:3])
        t = np.matrix(T_error[0:3,3]).T
        abs_disp.append(np.sqrt( R**2. / 5 * np.trace(A.T * A) + (t + A*xc).T * (t + A*xc) ).item())
        if prev_T!=None:
            T_error = T.as_affine() - prev_T.as_affine() # - np.eye(4)
            A = np.matrix(T_error[0:3,0:3])
            t = np.matrix(T_error[0:3,3]).T
            rel_disp.append(np.sqrt( R**2. / 5 * np.trace(A.T * A) + (t + A*xc).T * (t + A*xc) ).item())
        else:
            rel_disp.append(0.0)
        prev_T = T
    return aligned,np.array(abs_disp),np.array(rel_disp),np.array(transrot)
Ejemplo n.º 26
0
def load_specific_vol(vols, t, strict=False):
    """
    Utility function for loading specific volume on demand.

    Parameters
    ----------
    vols: string(s) or nibabel image object(s)
        input volumes or single 4D film
    t: int
        index of requested volume in the film

    """

    assert t >= 0

    if isinstance(vols, list):
        n_scans = len(vols)
        vol = load_vol(vols[t])
    elif is_niimg(vols) or isinstance(vols, basestring):
        _vols = nibabel.load(vols) if isinstance(vols, basestring) else vols
        if len(_vols.shape) != 4:
            if strict:
                raise ValueError("Expecting 4D image, got %iD" %
                                 len(_vols.shape))
            else:
                return _vols, 1

        n_scans = _vols.shape[-1]
        vol = nibabel.four_to_three(_vols)[t]
    else:  # unhandled type
        raise TypeError(("vols must be string, image object, or list of such; "
                         "got %s" % type(vols)))

    # delete trivial dimension
    if len(vol.shape) == 4:
        vol = nibabel.Nifti1Image(vol.get_data()[..., ..., ..., 0],
                                  vol.get_affine())

    assert is_niimg(vol)
    assert is_3D(vol)

    return vol, n_scans
Ejemplo n.º 27
0
def _load_mixed_gambles(zmap_imgs):
    """Ravel zmaps (one per subject) along time axis, resulting,
    in a n_subjects * n_trials 3D niimgs and, and then make
    gain vector y of same length.
    """
    X = []
    y = []
    mask = []
    for zmap_img in zmap_imgs:
        # load subject data
        this_X = zmap_img.get_data()
        affine = zmap_img.get_affine()
        finite_mask = np.all(np.isfinite(this_X), axis=-1)
        this_mask = np.logical_and(np.all(this_X != 0, axis=-1),
                                   finite_mask)
        this_y = np.array([np.arange(1, 9)] * 6).ravel()

        # gain levels
        if len(this_y) != this_X.shape[-1]:
            raise RuntimeError("%s: Expecting %i volumes, got %i!" % (
                zmap_img, len(this_y), this_X.shape[-1]))

        # standardize subject data
        this_X -= this_X.mean(axis=-1)[..., np.newaxis]
        std = this_X.std(axis=-1)
        std[std == 0] = 1
        this_X /= std[..., np.newaxis]

        # commit subject data
        X.append(this_X)
        y.extend(this_y)
        mask.append(this_mask)
    y = np.array(y)
    X = np.concatenate(X, axis=-1)
    mask = np.sum(mask, axis=0) > .5 * len(zmap_imgs)
    mask = np.logical_and(mask, np.all(np.isfinite(X), axis=-1))
    X = X[mask, :].T
    tmp = np.zeros(list(mask.shape) + [len(X)])
    tmp[mask, :] = X.T
    mask_img = nibabel.Nifti1Image(mask.astype(np.int), affine)
    X = nibabel.four_to_three(nibabel.Nifti1Image(tmp, affine))
    return X, y, mask_img
Ejemplo n.º 28
0
def load_craddock_2011(number_of_clusters: int, similarity_measure: str = 't', algorithm='2level') -> nibabel.Nifti1Image:
    """
    :param number_of_clusters: See the list of cluster sizes above or in volume_cluster_number.csv
    :param similarity_measure: t, s, or random (temporal, spatial, random)
    :param algorithm: 2level, mean, none
    :return:
    """
    if not ["t", "s", "random"].__contains__(similarity_measure):
        raise RuntimeError("%s is not a valid similarity measure for the craddock atlases. Please use 't', 's', 'random'" % similarity_measure)
    if not ["2level", "mean", None].__contains__(algorithm):
        raise RuntimeError(
            "%s is not a valid algorithm type for the craddock atlases. Please use '2level', 'mean', or None" % similarity_measure)
    if not CRADDOCK_CLUSTER_SIZES.__contains__(number_of_clusters):
        raise RuntimeError("%d is not a valid cluster size for the craddock atlases. Please use one of %s" % (number_of_clusters, str(CRADDOCK_CLUSTER_SIZES)))

    algorithm = algorithm + '_' if algorithm is not None else ''
    dataset_path = os.path.join(__get_data_folder_path(), 'craddock_2011', '%scorr05_%sall.nii.gz' % (similarity_measure, algorithm))
    dataset_img = nibabel.load(dataset_path)

    return nibabel.four_to_three(dataset_img)[CRADDOCK_CLUSTER_SIZES.index(number_of_clusters)]
Ejemplo n.º 29
0
def _flatten_split_merge(in_files):
    if isinstance(in_files, str):
        in_files = [in_files]

    nfiles = len(in_files)

    all_nii = []
    for fname in in_files:
        nii = nb.squeeze_image(nb.load(fname))

        if nii.get_data().ndim > 3:
            all_nii += nb.four_to_three(nii)
        else:
            all_nii.append(nii)

    if len(all_nii) == 1:
        LOGGER.warning('File %s cannot be split', all_nii[0])
        return in_files[0], in_files

    if len(all_nii) == nfiles:
        flat_split = in_files
    else:
        splitname = fname_presuffix(in_files[0],
                                    suffix='_split%04d',
                                    newpath=os.getcwd())
        flat_split = []
        for i, nii in enumerate(all_nii):
            flat_split.append(splitname % i)
            nii.to_filename(flat_split[-1])

    # Only one 4D file was supplied
    if nfiles == 1:
        merged = in_files[0]
    else:
        # More that one in_files - need merge
        merged = fname_presuffix(in_files[0],
                                 suffix='_merged',
                                 newpath=os.getcwd())
        nb.concat_images(all_nii).to_filename(merged)

    return merged, flat_split
Ejemplo n.º 30
0
def _make_sd(func_filenames=None,
             anat_filename=None,
             ext=".nii.gz",
             n_sessions=1,
             make_sess_dirs=False,
             func_ndim=4,
             unique_func_names=False,
             output_dir="/tmp/titi"):
    if not func_filenames is None:
        n_sessions = len(func_filenames)
    func = [create_random_image(ndim=func_ndim) for _ in range(n_sessions)]
    anat = create_random_image(ndim=3)
    if anat_filename is None:
        anat_filename = '%s/anat%s' % (DATA_DIR, ext)
    _save_img(anat, anat_filename)
    if not func_filenames is None:
        for sess_func, filename in zip(func, func_filenames):
            if isinstance(filename, str):
                _save_img(sess_func, filename)
            else:
                vols = nibabel.four_to_three(sess_func)
                for x, y in zip(vols, filename):
                    assert isinstance(y, str), type(y)
                    _save_img(x, y)
    else:
        func_filenames = []
        for sess in range(n_sessions):
            sess_dir = DATA_DIR if not make_sess_dirs else os.path.join(
                DATA_DIR, "session%i" % sess)
            if not os.path.exists(sess_dir):
                os.makedirs(sess_dir)
            func_filename = '%s/func%s%s' % (sess_dir, "_sess_%i_" % sess if (
                n_sessions > 1 and unique_func_names) else "", ext)
            _save_img(func[sess], func_filename)
            func_filenames.append(func_filename)

    sd = SubjectData(anat=anat_filename,
                     func=func_filenames,
                     output_dir=output_dir)
    return sd
Ejemplo n.º 31
0
def preprocess_fmri_fullbrain(experiment_data):
    # prepare the full-brain fMRI activation plots
    # http://nilearn.github.io/plotting/index.html
    fmri_data = nibabel.load(experiment_data['nifti_path'])
    fmri_data_slices = nibabel.four_to_three(fmri_data)
    for i in range(MAXIMUM_EPI_PLOTS):
        output_file_cond = os.path.join(
            os.path.dirname(__file__), '..', '..', 'temp', 'fmri',
            experiment_data['participant'] + '_fMRIfull_' + str(i) + '.png')

        # TODO make the cut slice configurable directly from the UI
        if OVERWRITE_EPI_PLOTS or not os.path.exists(output_file_cond):
            plotting.plot_img(fmri_data_slices[i],
                              output_file=output_file_cond,
                              title='Scan ' + str(i),
                              cut_coords=(config.FMRI_CUT_SLICE_X,
                                          config.FMRI_CUT_SLICE_Y,
                                          config.FMRI_CUT_SLICE_Z),
                              annotate=True,
                              draw_cross=True,
                              black_bg=True,
                              cmap=plt.cm.nipy_spectral)
Ejemplo n.º 32
0
def _flatten_split_merge(in_files):
    from builtins import bytes, str

    if isinstance(in_files, (bytes, str)):
        in_files = [in_files]

    nfiles = len(in_files)

    all_nii = []
    for fname in in_files:
        nii = nb.squeeze_image(nb.load(fname))

        if nii.get_data().ndim > 3:
            all_nii += nb.four_to_three(nii)
        else:
            all_nii.append(nii)

    if len(all_nii) == 1:
        LOGGER.warn('File %s cannot be split', all_nii[0])
        return in_files[0], in_files

    if len(all_nii) == nfiles:
        flat_split = in_files
    else:
        splitname = genfname(in_files[0], suffix='split%04d')
        flat_split = []
        for i, nii in enumerate(all_nii):
            flat_split.append(splitname % i)
            nii.to_filename(flat_split[-1])

    # Only one 4D file was supplied
    if nfiles == 1:
        merged = in_files[0]
    else:
        # More that one in_files - need merge
        merged = genfname(in_files[0], suffix='merged')
        nb.concat_images(all_nii).to_filename(merged)

    return merged, flat_split
Ejemplo n.º 33
0
 def normalization_intensity(self):
     for (input_nii_file, output_nii_file) in zip(self.smoothed_nii, self.intensity_norm_nii):
         print('run intensity normalization %s' % input_nii_file)
         print('generate %s' % output_nii_file)
         if os.path.exists(output_nii_file): continue
         dir_name = os.path.dirname(output_nii_file)
         if not os.path.exists(dir_name): os.makedirs(dir_name)
         nib_img = nib.load(input_nii_file)
         if len(nib_img.shape) > 3:
             nib_3d_imgs = nib.four_to_three(nib_img)
         else:
             nib_3d_imgs = [nib_img]
         dyn_3d_nib_files = []
         dyn_3d_nib_in_root = tempfile.mkdtemp()
         for nib_3d_img in nib_3d_imgs:
             nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz')
             nib_3d_img.to_filename(nib_3d_img_file)
             dyn_3d_nib_files.append(nib_3d_img_file)
         dyn_3d_nib_out_root = tempfile.mkdtemp()
         dyn_3d_nib_out_files = []
         for dyn_3d_nib_file in dyn_3d_nib_files:
             dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz')
             nib_3d_img = nib.load(dyn_3d_nib_file)
             np_3d_img = nib_3d_img.get_data()
             np_3d_img_norm = np_3d_img / np.mean(np_3d_img)
             nib_3d_img_norm = nib.Nifti1Image(np_3d_img_norm, nib_3d_img.affine)
             nib_3d_img_norm.to_filename(dyn_3d_nib_out_file)
             dyn_3d_nib_out_files.append(dyn_3d_nib_out_file)
         nib_3d_imgs = []
         for dyn_3d_nib_out_file in dyn_3d_nib_out_files:
             nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file))
         if len(nib_3d_imgs) > 1:
             nib_4d_img = nib.concat_images(nib_3d_imgs)
             nib_4d_img.to_filename(output_nii_file)
         else:
             nib_3d_imgs[0].to_filename(output_nii_file)
         if os.path.isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root)
         if os.path.isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root)
     return
def remove_bad_volumes(dwi, bvec_file, bval_file, base_name, thresh):
    import numpy as np
    import nibabel as nb
    import os.path as op
    from nipype.utils.filemanip import split_filename

    dwi_4D = nb.load(dwi)
    dwi_files = nb.four_to_three(dwi_4D)

    bvecs = np.transpose(np.loadtxt(bvec_file))
    bvals = np.transpose(np.loadtxt(bval_file))

    bad_indices = np.where(np.abs(bvecs[:,0]) >= thresh)[0]
    n_removed = len(bad_indices)

    dwi_files = [i for j, i in enumerate(dwi_files) if j not in bad_indices]
    bvecs = [i for j, i in enumerate(bvecs) if j not in bad_indices]
    bvals = [i for j, i in enumerate(bvals) if j not in bad_indices]

    corr_dwi = nb.concat_images(dwi_files)
    corr_bvecs = np.transpose(bvecs)
    corr_bvals = np.transpose(bvals)

    assert(len(dwi_files) == len(bvecs) == len(bvals))

    _, name, _ = split_filename(dwi)
    out_dwi = op.abspath(base_name + "%f_vib.nii.gz" % thresh)

    _, bvec_name, _ = split_filename(bvec_file)
    out_bvecs = op.abspath(base_name + "%f_vib.bvec"  % thresh)

    _, bval_name, _ = split_filename(bval_file)
    out_bvals = op.abspath(base_name + "%f_vib.bval"  % thresh)

    nb.save(corr_dwi, out_dwi)
    np.savetxt(out_bvecs, corr_bvecs)
    np.savetxt(out_bvals, corr_bvals)
    print("%d volumes were removed at threshold %f" % (n_removed, thresh))
    return out_dwi, out_bvecs, out_bvals, n_removed
Ejemplo n.º 35
0
def remove_bad_volumes(dwi, bvec_file, bval_file, thresh=0.8):
    import numpy as np
    import nibabel as nb
    import os.path as op
    from nipype.utils.filemanip import split_filename

    dwi_4D = nb.load(dwi)
    dwi_files = nb.four_to_three(dwi_4D)

    bvecs = np.transpose(np.loadtxt(bvec_file))
    bvals = np.transpose(np.loadtxt(bval_file))

    bad_indices = np.where(np.abs(bvecs[:,0]) >= thresh)[0]
    n_removed = len(bad_indices)

    dwi_files = [i for j, i in enumerate(dwi_files) if j not in bad_indices]
    bvecs = [i for j, i in enumerate(bvecs) if j not in bad_indices]
    bvals = [i for j, i in enumerate(bvals) if j not in bad_indices]

    corr_dwi = nb.concat_images(dwi_files)
    corr_bvecs = np.transpose(bvecs)
    corr_bvals = np.transpose(bvals)

    assert(len(dwi_files) == len(bvecs) == len(bvals))

    _, name, _ = split_filename(dwi)
    out_dwi = op.abspath(name + "_vib.nii.gz")

    _, bvec_name, _ = split_filename(bvec_file)
    out_bvecs = op.abspath(bvec_name + "_vib.bvec")

    _, bval_name, _ = split_filename(bval_file)
    out_bvals = op.abspath(bval_name + "_vib.bval")

    nb.save(corr_dwi, out_dwi)
    np.savetxt(out_bvecs, corr_bvecs)
    np.savetxt(out_bvals, corr_bvals)
    print("%d volumes were removed at threshold %f" % (n_removed, thresh))
    return out_dwi, out_bvecs, out_bvals, n_removed
Ejemplo n.º 36
0
 def smooth_gaussian(self):
     gaussian_filter = self.gaussian_filter
     for (input_nii_file, output_nii_file) in zip(self.normalized_nii,self.smoothed_nii):
         print('run gaussian smooth %s' % (input_nii_file))
         print('generate %s' % output_nii_file)
         if os.path.exists(output_nii_file): continue
         dir_name = os.path.dirname(output_nii_file)
         if not os.path.exists(dir_name): os.makedirs(dir_name)
         nib_img = nib.load(input_nii_file)
         if len(nib_img.shape) > 3:
             nib_3d_imgs = nib.four_to_three(nib_img)
         else:
             nib_3d_imgs = [nib_img]
         dyn_3d_nib_files = []
         dyn_3d_nib_in_root = tempfile.mkdtemp()
         for nib_3d_img in nib_3d_imgs:
             nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz')
             nib_3d_img.to_filename(nib_3d_img_file)
             dyn_3d_nib_files.append(nib_3d_img_file)
         dyn_3d_nib_out_root = tempfile.mkdtemp()
         dyn_3d_nib_out_files = []
         for dyn_3d_nib_file in dyn_3d_nib_files:
             dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz')
             sitk_image_0 = sitk.ReadImage(dyn_3d_nib_file)
             sitk_image_1 = sitk.SmoothingRecursiveGaussian(sitk_image_0, gaussian_filter)
             sitk.WriteImage(sitk_image_1, dyn_3d_nib_out_file)
             dyn_3d_nib_out_files.append(dyn_3d_nib_out_file)
         nib_3d_imgs = []
         for dyn_3d_nib_out_file in dyn_3d_nib_out_files:
             nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file))
         if len(nib_3d_imgs) > 1:
             nib_4d_img = nib.concat_images(nib_3d_imgs)
             nib_4d_img.to_filename(output_nii_file)
         else:
             nib_3d_imgs[0].to_filename(output_nii_file)
         if isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root)
         if isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root)
     return
Ejemplo n.º 37
0
def test_transform():
    # setup
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    film = nibabel.Nifti1Image(np.random.rand(11, 13, 17, 19), np.eye(4))
    threeD_vols = nibabel.four_to_three(film)

    # filenames
    film_filename = os.path.join(output_dir, 'film.nii.gz')
    threeD_vols_filenames = [
        os.path.join(output_dir, 'fMETHODS-%06i.nii' % i)
        for i in range(len(threeD_vols))
    ]

    for stuff in [film, threeD_vols]:
        for as_files in [False, True]:
            if as_files:
                if isinstance(stuff, list):
                    basenames = [
                        os.path.basename(x) for x in threeD_vols_filenames
                    ]
                else:
                    basenames = os.path.basename(film_filename)
                stuff = save_vols(stuff, output_dir, basenames=basenames)
            fmristc = fMRISTC().fit(raw_data=stuff)
            output = fmristc.transform(output_dir=output_dir)

            # test output type, shape, etc.
            if isinstance(stuff, list):
                assert isinstance(output, list)
                assert len(output) == film.shape[-1]
                if as_files:
                    assert os.path.basename(
                        output[7]) == 'afMETHODS-000007.nii'
            else:
                if as_files:
                    assert os.path.basename(output) == 'afilm.nii.gz'
Ejemplo n.º 38
0
 def __init__(self, archivePath, **entities):
     """
     Args:
         archivePath: Absolute path of the BIDS archive.
         entities: BIDS entities (subject, session, task, run, suffix, datatype) that
             define the particular subject/run of the data to stream
     """
     self.bidsArchive = BidsArchive(archivePath)
     # TODO - when we have BidsRun
     # self.bidsRun = self.bidsArchive.getBidsRun(**entities)
     images = self.bidsArchive.getImages(**entities)
     if len(images) == 0:
         raise ValidationError('No matching images found')
     if len(images) > 1:
         raise ValidationError('More than one match, please give more specific subject/session/task/run')
     self.bidsImage = images[0]
     self.niftiImage = self.bidsImage.get_image()
     self.filename = self.niftiImage.get_filename()
     self.imgVolumes = nib.four_to_three(self.niftiImage)
     self.metadata = self.bidsArchive.getSidecarMetadata(self.filename, includeEntities=True)
     self.metadata.pop('extension')
     self.numVolumes = len(self.imgVolumes)
     self.nextVol = 0
Ejemplo n.º 39
0
def _make_sd(func_filenames=None, anat_filename=None, ext=".nii.gz",
             n_sessions=1, make_sess_dirs=False,
             unique_func_names=False, output_dir="/tmp/titi"):
    if not func_filenames is None:
        n_sessions = len(func_filenames)
    func = [create_random_image(ndim=4) for _ in xrange(n_sessions)]
    anat = create_random_image(ndim=3)
    if anat_filename is None:
        anat_filename = '%s/anat%s' % (DATA_DIR, ext)
    _save_img(anat, anat_filename)
    if not func_filenames is None:
        for sess_func, filename in zip(func, func_filenames):
            if isinstance(filename, basestring):
                _save_img(sess_func, filename)
            else:
                vols = nibabel.four_to_three(sess_func)
                for x, y in zip(vols, filename):
                    assert isinstance(y, basestring), type(y)
                    _save_img(x, y)
    else:
        func_filenames = []
        for sess in xrange(n_sessions):
            sess_dir = DATA_DIR if not make_sess_dirs else os.path.join(
                DATA_DIR, "session%i" % sess)
            if not os.path.exists(sess_dir):
                os.makedirs(sess_dir)
            func_filename = '%s/func%s%s' % (
                sess_dir, "_sess_%i_" % sess if (
                    n_sessions > 1 and unique_func_names) else "", ext)
            _save_img(func[sess], func_filename)
            func_filenames.append(func_filename)

    sd = SubjectData(anat=anat_filename,
                     func=func_filenames,
                     output_dir=output_dir)

    return sd
Ejemplo n.º 40
0
def b0_average(in_file, out_file=None):
    """
    Average the b0 volumes.

    Args:
        in_file (str): The b0 volumes already registered.
        out_file (optional[str]): Name of the file.

    Returns:
        The mean of the b0 volumes.

    Warnings:
        The b0 volumes must be registered.
    """
    import os.path as op

    import nibabel as nb
    import numpy as np

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_file))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_avg_b0%s" % (fname, ext))

    imgs = np.array(nb.four_to_three(nb.load(in_file)))
    b0s = [im.get_data().astype(np.float32) for im in imgs]
    b0 = np.average(np.array(b0s), axis=0)

    hdr = imgs[0].get_header().copy()
    hdr.set_data_shape(b0.shape)
    hdr.set_xyzt_units("mm")
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file)

    return out_file
Ejemplo n.º 41
0
    def _run_interface(self, runtime):
        nii_list = []
        for f in self.inputs.in_files:
            filenii = nb.squeeze_image(nb.load(f))
            ndim = filenii.dataobj.ndim
            if ndim == 3:
                nii_list.append(filenii)
                continue
            elif self.inputs.allow_4D and ndim == 4:
                nii_list += nb.four_to_three(filenii)
                continue
            else:
                raise ValueError(
                    "Input image has an incorrect number of dimensions"
                    f" ({ndim}).")

        img_4d = nb.concat_images(nii_list)
        out_file = fname_presuffix(self.inputs.in_files[0],
                                   suffix="_merged",
                                   newpath=runtime.cwd)
        img_4d.to_filename(out_file)

        self._results["out_file"] = out_file
        return runtime
Ejemplo n.º 42
0
def time_avg(in_file, index=[0], out_file=None):
    """
    Average the input time-series, selecting the indices given in index

    .. warning:: time steps should be already registered (corrected for
      head motion artifacts).

    """
    import numpy as np
    import nibabel as nb
    import os.path as op
    from nipype.utils import NUMPY_MMAP

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_file))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_baseline%s" % (fname, ext))

    index = np.atleast_1d(index).tolist()

    imgs = np.array(nb.four_to_three(nb.load(in_file, mmap=NUMPY_MMAP)))[index]
    if len(index) == 1:
        data = imgs[0].get_data().astype(np.float32)
    else:
        data = np.average(np.array(
            [im.get_data().astype(np.float32) for im in imgs]),
                          axis=0)

    hdr = imgs[0].header.copy()
    hdr.set_data_shape(data.shape)
    hdr.set_xyzt_units('mm')
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(data, imgs[0].affine, hdr).to_filename(out_file)
    return out_file
Ejemplo n.º 43
0
def b0_average(in_dwi, in_bval, max_b=10.0, out_file=None):
    """
    A function that averages the *b0* volumes from a DWI dataset.
    As current dMRI data are being acquired with all b-values > 0.0,
    the *lowb* volumes are selected by specifying the parameter max_b.

    .. warning:: *b0* should be already registered (head motion artifact should
      be corrected).

    """
    import numpy as np
    import nibabel as nb
    import os.path as op
    from nipype.utils import NUMPY_MMAP

    if out_file is None:
        fname, ext = op.splitext(op.basename(in_dwi))
        if ext == ".gz":
            fname, ext2 = op.splitext(fname)
            ext = ext2 + ext
        out_file = op.abspath("%s_avg_b0%s" % (fname, ext))

    imgs = np.array(nb.four_to_three(nb.load(in_dwi, mmap=NUMPY_MMAP)))
    bval = np.loadtxt(in_bval)
    index = np.argwhere(bval <= max_b).flatten().tolist()

    b0s = [im.get_data().astype(np.float32)
           for im in imgs[index]]
    b0 = np.average(np.array(b0s), axis=0)

    hdr = imgs[0].header.copy()
    hdr.set_data_shape(b0.shape)
    hdr.set_xyzt_units('mm')
    hdr.set_data_dtype(np.float32)
    nb.Nifti1Image(b0, imgs[0].affine, hdr).to_filename(out_file)
    return out_file
Ejemplo n.º 44
0
def test_load_4D_img():
    # setup
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # try loading from 4D niimg
    film = create_random_image(n_scans=10)
    loaded_4D_img = load_4D_img(film)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from 4D image file
    film = create_random_image(n_scans=10)
    saved_img_filename = os.path.join(output_dir, "4D.nii.gz")
    nibabel.save(film, saved_img_filename)
    loaded_4D_img = load_4D_img(saved_img_filename)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from list of 3D niimgs
    film = create_random_image(n_scans=10)
    loaded_4D_img = load_4D_img(nibabel.four_to_three(film))
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)

    # try loading from list of 3D image files
    film = create_random_image(n_scans=10)
    saved_vols_filenames = save_vols(
        film,
        output_dir,
        ext='.nii.gz',
    )
    loaded_4D_img = load_4D_img(saved_vols_filenames)
    assert_true(is_niimg(loaded_4D_img))
    assert_equal(loaded_4D_img.shape, film.shape)
Ejemplo n.º 45
0
    def _run_interface(self, runtime):
        iflogger.info(
            'Segmentation image: {img}'.format(img=self.inputs.segmentation_file))
        rois = get_roi_list(self.inputs.segmentation_file)
        number_of_nodes = len(rois)
        iflogger.info('Found {roi} unique region values'.format(roi=len(rois)))

        if len(self.inputs.in_files) > 1:
            iflogger.info('Multiple input images detected')
            iflogger.info(len(self.inputs.in_files))
            in_files = self.inputs.in_files
            try:
                # VERY tempermental solution to sorting the functional images.
                # RELIES ON xyz-01_out.nii from recent resampling.
                in_files = sorted(in_files, key=lambda x:
                                  int(x.split("_")[-2].split("-")[-2]))
            except IndexError:
                # Tempermental solution to sorting the functional images.
                # RELIES ON xyz_out.nii from recent resampling.
                in_files = sorted(in_files, key=lambda x:
                                  int(x.split("_")[-2]))
        elif isdefined(self.inputs.in_file4d):
            iflogger.info('Single four-dimensional image selected')
            in_file4d = nb.load(self.inputs.in_file4d)
            in_files = nb.four_to_three(in_file4d)
        else:
            iflogger.info('Single functional image provided')
            in_files = self.inputs.in_files

        rois = get_roi_list(self.inputs.segmentation_file)
        fMRI_timecourse, _, _, _, _ = get_timecourse_by_region(
            in_files, self.inputs.segmentation_file, rois)
        timecourse_at_each_node = fMRI_timecourse.T
        time_course_image = nb.load(self.inputs.time_course_file)

        iflogger.info(np.shape(timecourse_at_each_node))

        number_of_components = 30
        number_of_images = 198
        time_course_data = time_course_image.get_data()
        onerow = np.ones(number_of_images)
        time_course_per_IC = np.vstack((onerow.T, time_course_data.T)).T
        iflogger.info(np.shape(time_course_per_IC))

        y = timecourse_at_each_node
        X = time_course_per_IC
        n = number_of_images
        XTX_inv = np.linalg.inv(np.dot(X.T, X))
        N = number_of_components + 1
        contrast = np.concatenate(
            (np.zeros((1, number_of_components)), np.eye(number_of_components))).T
        a = np.empty((number_of_nodes, N))
        residues = np.empty((number_of_nodes, 1))
        rank = np.empty((number_of_nodes, 1))
        singularvalues = np.empty((number_of_nodes, N))
        resids = np.empty((number_of_nodes, number_of_images))
        error_variance = np.empty((number_of_nodes, 1))
        t_values = np.empty((number_of_nodes, number_of_components))
        beta_value = np.empty((number_of_components, 1))
        for node_idx, node in enumerate(rois):
            a[node_idx], residues[node_idx], rank[node_idx], singularvalues[
                node_idx] = np.linalg.lstsq(X, y[:, node_idx])
            resids[node_idx, :] = y[:, node_idx] - \
                np.dot(X, a[node_idx])       # e = y - Xa;
            error_variance[node_idx] = np.var(resids[node_idx])
            for IC in range(0, number_of_components):
                t_values[node_idx, IC] = np.dot(contrast[IC], a[node_idx]) / \
                    np.sqrt(
                        error_variance[node_idx] * np.dot(np.dot(contrast[IC], XTX_inv), contrast[IC, :].T))
                beta_value[IC] = np.dot(contrast[IC], a[node_idx])

        t_value_dict = {}
        t_value_dict['t_value_per_node'] = t_values
        t_value_dict['timecourse_at_each_node'] = y
        t_value_dict['timecourse_per_IC'] = X
        t_value_dict['number_of_images'] = n
        t_value_dict['a'] = a
        t_value_dict['contrast'] = contrast
        t_value_dict['residuals'] = resids
        t_value_dict['error_variance'] = error_variance

        out_file = op.abspath(self.inputs.out_t_value_threshold_file)
        iflogger.info(
            'Saving T-values per node, per IC, as {file}'.format(file=out_file))
        sio.savemat(out_file, t_value_dict)
        return runtime
Ejemplo n.º 46
0
def nonlinfit_fn(dwi, bvecs, bvals, base_name):
    import nibabel as nb
    import numpy as np
    import os.path as op
    import dipy.reconst.dti as dti
    from dipy.core.gradients import GradientTable

    dwi_img = nb.load(dwi)
    dwi_data = dwi_img.get_data()
    dwi_affine = dwi_img.get_affine()
    
    from dipy.segment.mask import median_otsu
    b0_mask, mask = median_otsu(dwi_data, 2, 4)
    # Mask the data so that tensors are not fit for
    # unnecessary voxels
    mask_img = nb.Nifti1Image(mask.astype(np.float32), dwi_affine)
    b0_imgs = nb.Nifti1Image(b0_mask.astype(np.float32), dwi_affine)
    b0_img = nb.four_to_three(b0_imgs)[0]

    out_mask_name = op.abspath(base_name + '_binary_mask.nii.gz')
    out_b0_name = op.abspath(base_name + '_b0_mask.nii.gz')
    nb.save(mask_img, out_mask_name)
    nb.save(b0_img, out_b0_name)

    # Load the gradient strengths and directions
    bvals = np.loadtxt(bvals)
    gradients = np.loadtxt(bvecs)

    # Dipy wants Nx3 arrays
    if gradients.shape[0] == 3:
        gradients = gradients.T
        assert(gradients.shape[1] == 3)

    # Place in Dipy's preferred format
    gtab = GradientTable(gradients)
    gtab.bvals = bvals

    # Fit the tensors to the data
    tenmodel = dti.TensorModel(gtab, fit_method="NLLS")
    tenfit = tenmodel.fit(dwi_data, mask)

    # Calculate the fit, fa, and md of each voxel's tensor
    tensor_data = tenfit.lower_triangular()
    print('Computing anisotropy measures (FA, MD, RGB)')
    from dipy.reconst.dti import fractional_anisotropy, color_fa

    evals = tenfit.evals.astype(np.float32)
    FA = fractional_anisotropy(np.abs(evals))
    FA = np.clip(FA, 0, 1)

    MD = dti.mean_diffusivity(np.abs(evals))
    norm = dti.norm(tenfit.quadratic_form)

    RGB = color_fa(FA, tenfit.evecs)

    evecs = tenfit.evecs.astype(np.float32)
    mode = tenfit.mode.astype(np.float32)
    mode = np.nan_to_num(mode)


    # Write tensor as a 4D Nifti image with the original affine
    tensor_fit_img = nb.Nifti1Image(tensor_data.astype(np.float32), dwi_affine)
    mode_img = nb.Nifti1Image(mode.astype(np.float32), dwi_affine)
    norm_img = nb.Nifti1Image(norm.astype(np.float32), dwi_affine)
    FA_img = nb.Nifti1Image(FA.astype(np.float32), dwi_affine)
    evecs_img = nb.Nifti1Image(evecs, dwi_affine)
    evals_img = nb.Nifti1Image(evals, dwi_affine)
    rgb_img = nb.Nifti1Image(np.array(255 * RGB, 'uint8'), dwi_affine)
    MD_img = nb.Nifti1Image(MD.astype(np.float32), dwi_affine)

    out_tensor_file = op.abspath(base_name + "_tensor.nii.gz")
    out_mode_file = op.abspath(base_name + "_mode.nii.gz")
    out_fa_file = op.abspath(base_name + "_fa.nii.gz")
    out_norm_file = op.abspath(base_name + "_norm.nii.gz")
    out_evals_file = op.abspath(base_name + "_evals.nii.gz")
    out_evecs_file = op.abspath(base_name + "_evecs.nii.gz")
    out_rgb_fa_file = op.abspath(base_name + "_rgb_fa.nii.gz")
    out_md_file = op.abspath(base_name + "_md.nii.gz")

    nb.save(rgb_img, out_rgb_fa_file)
    nb.save(norm_img, out_norm_file)
    nb.save(mode_img, out_mode_file)
    nb.save(tensor_fit_img, out_tensor_file)
    nb.save(evecs_img, out_evecs_file)
    nb.save(evals_img, out_evals_file)
    nb.save(FA_img, out_fa_file)
    nb.save(MD_img, out_md_file)
    print('Tensor fit image saved as {i}'.format(i=out_tensor_file))
    print('FA image saved as {i}'.format(i=out_fa_file))
    print('MD image saved as {i}'.format(i=out_md_file))
    return out_tensor_file, out_fa_file, out_md_file, \
        out_evecs_file, out_evals_file, out_rgb_fa_file, out_norm_file, \
        out_mode_file, out_mask_name, out_b0_name
Ejemplo n.º 47
0
    def _run_interface(self, runtime):
        from dipy.core.gradients import GradientTable
        from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity
        from dipy.reconst.csdeconv import recursive_response, auto_response

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.affine

        if isdefined(self.inputs.in_mask):
            msk = nb.load(self.inputs.in_mask).get_data()
            msk[msk > 0] = 1
            msk[msk < 0] = 0
        else:
            msk = np.ones(imref.shape)

        data = img.get_data().astype(np.float32)
        gtab = self._get_gradient_table()

        evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data())
        FA = np.nan_to_num(fractional_anisotropy(evals)) * msk
        indices = np.where(FA > self.inputs.fa_thresh)
        S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]]
        S0 = np.mean(S0s)

        if self.inputs.auto:
            response, ratio = auto_response(gtab,
                                            data,
                                            roi_radius=self.inputs.roi_radius,
                                            fa_thr=self.inputs.fa_thresh)
            response = response[0].tolist() + [S0]
        elif self.inputs.recursive:
            MD = np.nan_to_num(mean_diffusivity(evals)) * msk
            indices = np.logical_or(FA >= 0.4,
                                    (np.logical_and(FA >= 0.15, MD >= 0.0011)))
            data = nb.load(self.inputs.in_file).get_data()
            response = recursive_response(gtab,
                                          data,
                                          mask=indices,
                                          sh_order=8,
                                          peak_thr=0.01,
                                          init_fa=0.08,
                                          init_trace=0.0021,
                                          iter=8,
                                          convergence=0.001,
                                          parallel=True)
            ratio = abs(response[1] / response[0])
        else:
            lambdas = evals[indices]
            l01 = np.sort(np.mean(lambdas, axis=0))

            response = np.array([l01[-1], l01[-2], l01[-2], S0])
            ratio = abs(response[1] / response[0])

        if ratio > 0.25:
            IFLOGGER.warn(
                'Estimated response is not prolate enough. '
                'Ratio=%0.3f.', ratio)
        elif ratio < 1.e-5 or np.any(np.isnan(response)):
            response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0])
            IFLOGGER.warn(
                'Estimated response is not valid, using a default one')
        else:
            IFLOGGER.info('Estimated response: %s', str(response[:3]))

        np.savetxt(op.abspath(self.inputs.response), response)

        wm_mask = np.zeros_like(FA)
        wm_mask[indices] = 1
        nb.Nifti1Image(wm_mask.astype(np.uint8), affine,
                       None).to_filename(op.abspath(self.inputs.out_mask))
        return runtime
Ejemplo n.º 48
0
    def _run_interface(self, runtime):
        in_files = self.inputs.in_files
        if not isinstance(in_files, list):
            in_files = [self.inputs.in_files]

        if self.inputs.to_ras:
            in_files = [reorient(inf, newpath=runtime.cwd) for inf in in_files]

        run_hmc = self.inputs.hmc and len(in_files) > 1

        nii_list = []
        # Remove one-sized extra dimensions
        for i, f in enumerate(in_files):
            filenii = nb.load(f)
            filenii = nb.squeeze_image(filenii)
            if len(filenii.shape) == 5:
                raise RuntimeError("Input image (%s) is 5D." % f)
            if filenii.dataobj.ndim == 4:
                nii_list += nb.four_to_three(filenii)
            else:
                nii_list.append(filenii)

        if len(nii_list) > 1:
            filenii = nb.concat_images(nii_list)
        else:
            filenii = nii_list[0]

        merged_fname = fname_presuffix(self.inputs.in_files[0],
                                       suffix="_merged",
                                       newpath=runtime.cwd)
        filenii.to_filename(merged_fname)
        self._results["out_file"] = merged_fname
        self._results["out_avg"] = merged_fname

        if filenii.dataobj.ndim < 4:
            # TODO: generate identity out_mats and zero-filled out_movpar
            return runtime

        if run_hmc:
            mcflirt = fsl.MCFLIRT(
                cost="normcorr",
                save_mats=True,
                save_plots=True,
                ref_vol=0,
                in_file=merged_fname,
            )
            mcres = mcflirt.run()
            filenii = nb.load(mcres.outputs.out_file)
            self._results["out_file"] = mcres.outputs.out_file
            self._results["out_mats"] = mcres.outputs.mat_file
            self._results["out_movpar"] = mcres.outputs.par_file

        hmcdata = filenii.get_fdata(dtype="float32")
        if self.inputs.grand_mean_scaling:
            if not isdefined(self.inputs.in_mask):
                mean = np.median(hmcdata, axis=-1)
                thres = np.percentile(mean, 25)
                mask = mean > thres
            else:
                mask = nb.load(
                    self.inputs.in_mask).get_fdata(dtype="float32") > 0.5

            nimgs = hmcdata.shape[-1]
            means = np.median(hmcdata[mask[..., np.newaxis]].reshape(
                (-1, nimgs)).T,
                              axis=-1)
            max_mean = means.max()
            for i in range(nimgs):
                hmcdata[..., i] *= max_mean / means[i]

        hmcdata = hmcdata.mean(axis=3)
        if self.inputs.zero_based_avg:
            hmcdata -= hmcdata.min()

        self._results["out_avg"] = fname_presuffix(self.inputs.in_files[0],
                                                   suffix="_avg",
                                                   newpath=runtime.cwd)
        nb.Nifti1Image(hmcdata, filenii.affine,
                       filenii.header).to_filename(self._results["out_avg"])

        return runtime
Ejemplo n.º 49
0
    def _run_interface(self, runtime):
        from dipy.reconst.peaks import peaks_from_model
        from dipy.tracking.eudx import EuDX
        from dipy.data import get_sphere
        # import marshal as pickle
        import pickle as pickle
        import gzip

        if (not (isdefined(self.inputs.in_model)
                 or isdefined(self.inputs.in_peaks))):
            raise RuntimeError(('At least one of in_model or in_peaks should '
                                'be supplied'))

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.affine

        data = img.get_data().astype(np.float32)
        hdr = imref.header.copy()
        hdr.set_data_dtype(np.float32)
        hdr['data_type'] = 16

        sphere = get_sphere('symmetric724')

        self._save_peaks = False
        if isdefined(self.inputs.in_peaks):
            IFLOGGER.info('Peaks file found, skipping ODF peaks search...')
            f = gzip.open(self.inputs.in_peaks, 'rb')
            peaks = pickle.load(f)
            f.close()
        else:
            self._save_peaks = True
            IFLOGGER.info('Loading model and computing ODF peaks')
            f = gzip.open(self.inputs.in_model, 'rb')
            odf_model = pickle.load(f)
            f.close()

            peaks = peaks_from_model(
                model=odf_model,
                data=data,
                sphere=sphere,
                relative_peak_threshold=self.inputs.peak_threshold,
                min_separation_angle=self.inputs.min_angle,
                parallel=self.inputs.multiprocess)

            f = gzip.open(self._gen_filename('peaks', ext='.pklz'), 'wb')
            pickle.dump(peaks, f, -1)
            f.close()

        hdr.set_data_shape(peaks.gfa.shape)
        nb.Nifti1Image(peaks.gfa.astype(np.float32), affine,
                       hdr).to_filename(self._gen_filename('gfa'))

        IFLOGGER.info('Performing tractography')

        if isdefined(self.inputs.tracking_mask):
            msk = nb.load(self.inputs.tracking_mask).get_data()
            msk[msk > 0] = 1
            msk[msk < 0] = 0
        else:
            msk = np.ones(imref.shape)

        gfa = peaks.gfa * msk
        seeds = self.inputs.num_seeds

        if isdefined(self.inputs.seed_coord):
            seeds = np.loadtxt(self.inputs.seed_coord)

        elif isdefined(self.inputs.seed_mask):
            seedmsk = nb.load(self.inputs.seed_mask).get_data()
            assert (seedmsk.shape == data.shape[:3])
            seedmsk[seedmsk > 0] = 1
            seedmsk[seedmsk < 1] = 0
            seedps = np.array(np.where(seedmsk == 1), dtype=np.float32).T
            vseeds = seedps.shape[0]
            nsperv = (seeds // vseeds) + 1
            IFLOGGER.info(
                'Seed mask is provided (%d voxels inside '
                'mask), computing seeds (%d seeds/voxel).', vseeds, nsperv)
            if nsperv > 1:
                IFLOGGER.info('Needed %d seeds per selected voxel (total %d).',
                              nsperv, vseeds)
                seedps = np.vstack(np.array([seedps] * nsperv))
                voxcoord = seedps + np.random.uniform(-1, 1, size=seedps.shape)
                nseeds = voxcoord.shape[0]
                seeds = affine.dot(
                    np.vstack((voxcoord.T, np.ones((1, nseeds)))))[:3, :].T

                if self.inputs.save_seeds:
                    np.savetxt(self._gen_filename('seeds', ext='.txt'), seeds)

        if isdefined(self.inputs.tracking_mask):
            tmask = msk
            a_low = 0.1
        else:
            tmask = gfa
            a_low = self.inputs.gfa_thresh

        eu = EuDX(tmask,
                  peaks.peak_indices[..., 0],
                  seeds=seeds,
                  affine=affine,
                  odf_vertices=sphere.vertices,
                  a_low=a_low)

        ss_mm = [np.array(s) for s in eu]

        trkfilev = nb.trackvis.TrackvisFile([(s, None, None) for s in ss_mm],
                                            points_space='rasmm',
                                            affine=np.eye(4))
        trkfilev.to_file(self._gen_filename('tracked', ext='.trk'))
        return runtime
Ejemplo n.º 50
0
    def _run_interface(self, runtime):

        # Determine the parameters
        experiment = self.inputs.experiment
        subject, session, run = self.inputs.run
        self._results["run_tuple"] = self.inputs.run
        self._results["subject"] = subject
        self._results["session"] = session
        self._results["run"] = run

        # Spec out paths to the input files
        keys = dict(subject=subject, experiment=experiment,
                    session=session, run=run)
        sb_fname = op.join(self.inputs.data_dir, subject, "func",
                           self.inputs.sb_template.format(**keys))
        ts_fname = op.join(self.inputs.data_dir, subject, "func",
                           self.inputs.ts_template.format(**keys))

        # Load the input images in canonical orientation
        sb_img = nib.as_closest_canonical(nib.load(sb_fname))
        ts_img = nib.as_closest_canonical(nib.load(ts_fname))

        # Convert image datatypes to float
        sb_img.set_data_dtype(np.float32)
        ts_img.set_data_dtype(np.float32)

        # Optionally crop the first n frames of the timeseries
        if self.inputs.crop_frames > 0:
            ts_data = ts_img.get_data()
            ts_data = ts_data[..., self.inputs.crop_frames:]
            ts_img = nib.Nifti1Image(ts_data, ts_img.affine, ts_img.header)

        # Write out the new images
        self.write_image("sb_file", "sb.nii.gz", sb_img)
        self.write_image("ts_file", "ts.nii.gz", ts_img)

        # Write out each frame of the timeseries
        os.mkdir("frames")
        ts_frames = []
        ts_frame_imgs = nib.four_to_three(ts_img)
        for i, frame_img in enumerate(ts_frame_imgs):
            frame_fname = op.abspath("frames/frame{:04d}.nii.gz".format(i))
            ts_frames.append(frame_fname)
            frame_img.to_filename(frame_fname)
        self._results["ts_frames"] = ts_frames

        # Make a GIF movie of the raw timeseries
        out_plot = self.define_output("ts_plot", "raw.gif")
        self.write_time_series_gif(runtime, ts_img, out_plot)

        # Load files from the template directory
        template_path = op.join(self.inputs.proc_dir, subject, "template")
        results = dict(
            reg_file=op.join(template_path, "anat2func.mat"),
            seg_file=op.join(template_path, "seg.nii.gz"),
            anat_file=op.join(template_path, "anat.nii.gz"),
            mask_file=op.join(template_path, "mask.nii.gz"),
        )
        self._results.update(results)

        return runtime
Ejemplo n.º 51
0
 def _save_2_pet_suv_bqml(self,
                          series_dicom_root,
                          sub_root,
                          sub_name='sub-001',
                          func_name='pet',
                          task_name='rest'):
     # find udcm2bids tags and calc convert factor
     func_root = os.path.join(sub_root, func_name)
     bqml_nii_file = os.path.join(
         func_root, sub_name + '_task-' + task_name + '_PET-BQML.nii.gz')
     suvbw_nii_file = bqml_nii_file.replace('_PET-BQML', '_PET-SUVbw')
     suvbw_json_file = suvbw_nii_file.replace('.nii.gz', '.json')
     if os.path.exists(suvbw_nii_file): return
     suv_factor = []
     acqdatetime = []
     dicom_files = glob(os.path.join(series_dicom_root, '*.dcm'))
     for i, file in enumerate(dicom_files):
         ds = pydicom.read_file(file, stop_before_pixels=False)
         dt = str(ds.AcquisitionDateTime)[:14]
         if dt not in acqdatetime:
             acqdatetime.append(dt)
             suv_factor.append(self._calc_uih_pet_suvbw_factor(ds))
     # convert to bids
     if not os.path.isdir(func_root): os.mkdir(func_root)
     # check whether exist or not
     if not os.path.exists(bqml_nii_file):
         devnull = open(os.devnull, 'w')
         subprocess.call([
             'dcm2niix', '-b', 'y', '-z', 'y', '-f', sub_name + '_task-' +
             task_name + '_PET-BQML', '-o', func_root, series_dicom_root
         ],
                         stdout=devnull,
                         stderr=subprocess.STDOUT)
     # convert bqml to suv_bw with suv_factor
     nib_img_bqml = nib.load(bqml_nii_file)
     if len(suv_factor) > 1:
         nib_3d_imgs_bqml = nib.four_to_three(nib_img_bqml)
         np_3d_imgs_bqml = [
             nib_3d_img_bqml.get_data()
             for nib_3d_img_bqml in nib_3d_imgs_bqml
         ]
         affines = [
             nib_3d_img_bqml.affine for nib_3d_img_bqml in nib_3d_imgs_bqml
         ]
         np_3d_imgs_suvbw = [
             np_3d_img * c_factor
             for np_3d_img, c_factor in zip(np_3d_imgs_bqml, suv_factor)
         ]
         nib_3d_imgs_suvbw = [
             nib.Nifti1Image(new_np_3d_img, affine)
             for new_np_3d_img, affine in zip(np_3d_imgs_suvbw, affines)
         ]
         nib_img_suvbw = nib.concat_images(nib_3d_imgs_suvbw)
         nib_img_suvbw.to_filename(suvbw_nii_file)
     else:
         nib_3d_img_bqml = nib_img_bqml
         np_3d_img_bqml = nib_3d_img_bqml.get_data()
         affine = nib_3d_img_bqml.affine
         np_3d_img_suvbw = np_3d_img_bqml * suv_factor[0]
         nib_3d_img_suvbw = nib.Nifti1Image(np_3d_img_suvbw, affine)
         nib_3d_img_suvbw.to_filename(suvbw_nii_file)
     with open(suvbw_json_file, 'wt', encoding='utf-8') as f_json:
         json.dump(
             {
                 'suvbw_factor': suv_factor,
                 'acquisition_time': acqdatetime
             },
             f_json,
             indent=4)
     return
Ejemplo n.º 52
0
    def _run_interface(self, runtime):

        # Load the 4D raw fieldmap image and select first frame
        raw_img_frames = nib.load(self.inputs.raw_file)
        raw_img = nib.four_to_three(raw_img_frames)[0]
        affine, header = raw_img.affine, raw_img.header

        # Write out the raw image to serve as a registration target
        self.write_image("raw_file", "raw.nii.gz", raw_img)

        # Load the 4D jacobian image
        jac_img_frames = nib.concat_images(self.inputs.jacobian_files)
        jac_data = jac_img_frames.get_data()

        # Load the 4D corrected fieldmap image
        corr_img_frames = nib.load(self.inputs.corrected_file)
        corr_data = corr_img_frames.get_data()

        # Jacobian modulate the corrected image
        corr_mod_data = corr_data * jac_data
        corr_img_frames = nib.Nifti1Image(corr_mod_data, affine, header)

        # Average the corrected image over the final dimension and write
        corr_mod_data = corr_mod_data.mean(axis=-1)
        self.write_image("corrected_file", "func.nii.gz",
                         corr_mod_data, affine, header)

        # Save the jacobian images using the raw geometry
        self.write_image("jacobian_file", "jacobian.nii.gz",
                         jac_data, affine, header)

        # Select the first warpfield image
        # We combine the two fieldmap images so that the first one has
        # a phase encoding that matches the time series data.
        # Also note that when the fieldmap images have multiple frames,
        # the warps corresponding to those frames are identical.
        warp_file = self.inputs.warp_files[0]

        # Load in the the warp file and save out with the correct affine
        # (topup doesn't save the header geometry correctly for some reason)
        warp_data = nib.load(warp_file).get_data()
        self.write_image("warp_file", "warp.nii.gz", warp_data, affine, header)

        # Select the warp along the phase encode direction
        # Note: we elsewhere currently require phase encoding to be AP or PA
        # so because the input node transforms the fieldmap to canonical
        # orientation this will work. But in the future we might want to ne
        # more flexible with what we accept and will need to change this.
        warp_data_y = warp_data[..., 1]

        # Write out a mask to exclude voxels with large distortions/dropout
        mask_data = (np.abs(warp_data_y) < 4).astype(np.int)
        self.write_image("mask_file", "warp_mask.nii.gz",
                         mask_data, affine, header)

        # Generate a QC image of the warpfield
        m = Mosaic(raw_img, warp_data_y)
        m.plot_overlay("coolwarm", vmin=-6, vmax=6, alpha=.75)
        self.write_visualization("warp_plot", "warp.png", m)

        # Generate a QC gif of the unwarping performance
        self.generate_unwarp_gif(runtime, raw_img_frames, corr_img_frames)

        return runtime
Ejemplo n.º 53
0
def save_vols(vols, output_dir, basenames=None, affine=None,
              concat=False, prefix='', ext=None):
    """
    Saves a single 4D image or a couple of 3D vols unto disk.

    vols: single 4D nibabel image object, or list of 3D nibabel image objects
        volumes, of ndarray
        volumes to be saved

    output_dir: string
        existing filename, destination directory

    basenames: string or list of string, optional (default None)
        basename(s) for output image(s)

    affine: 2D array of shape (4, 4)
        affine matrix for the output images

    concat: bool, optional (default False)
        concatenate all vols into a single film

    prefix: string, optional (default '')
       prefix to be prepended to output file basenames

    ext: string, optional (default ".nii.gz")
        file extension for output images

    Returns
    -------
    string of list of strings, dependending on whether vols is list or
    not, and on whether concat is set or not
        the output image filename(s)

    """

    def _nifti_or_ndarray_to_nifti(x):
        if is_niimg(x):
            if not affine is None:
                raise ValueError(
                    ("vol is of type %s; not expecting `affine` parameter."
                     ) % type(x))
            else:
                return x

        if affine is None:
            raise ValueError(
                "vol is of type ndarray; you need to specifiy `affine`")
        else:
            return nibabel.Nifti1Image(x, affine)

    if not basenames is None:
        basenames = get_basenames(basenames, ext=ext)

    # sanitize output_dir
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # vols are ndarray ?
    if isinstance(vols, np.ndarray):
        vols = _nifti_or_ndarray_to_nifti(vols)

    # concat vols to single 4D film ?
    if concat:
        if isinstance(vols, list):
            vols = nibabel.concat_images([_nifti_or_ndarray_to_nifti(vol)
                                  for vol in vols],
                                         check_affines=False
                                         )
            if not basenames is None:
                if not isinstance(basenames, basestring):
                    basenames = basenames[0]
        else:
            if not basenames is None:
                if not isinstance(basenames, basestring):
                    raise RuntimeError(
                        ("concat=True specified but basenames is of type %s "
                         "instead of string") % type(basenames))

    if not isinstance(vols, list):
        if basenames is None:
            basenames = get_basenames("vols", ext=ext)

        if not isinstance(basenames, basestring):
            vols = nibabel.four_to_three(vols)
            filenames = []
            for vol, basename in zip(vols, basenames):
                assert isinstance(basename, basestring)
                filename = os.path.join(output_dir, "%s%s" % (
                        prefix, basename))
                nibabel.save(vol, filename)
                filenames.append(filename)
        else:
            filenames = os.path.join(output_dir, "%s%s" % (
                    prefix, basenames))
            nibabel.save(vols, filenames)

        return filenames
    else:
        n_vols = len(vols)
        filenames = []

        if basenames is None:
            if prefix:
                prefix = prefix + "_"
        else:
            if isinstance(basenames, basestring):
                basenames = ["vol%i_%s" % (t, basenames)
                             for t in xrange(len(vols))]
            else:
                assert len(set(basenames)) == len(vols), basenames

        for t, vol in zip(xrange(n_vols), vols):
            if isinstance(vol, np.ndarray):
                if affine is None:
                    raise ValueError(
                        ("vols is of type ndarray; you need to specifiy"
                         " `affine`"))
                else:
                    vol = nibabel.Nifti1Image(vol, affine)

            # save realigned vol unto disk
            if basenames is None:
                if ext is None:
                    ext = ".nii.gz"
                output_filename = os.path.join(output_dir,
                                               get_basename("%svol_%i" % (
                            prefix, t), ext=ext))
            else:
                basename = basenames if isinstance(
                    basenames, basestring) else basenames[t]
                output_filename = os.path.join(output_dir,
                                               get_basenames("%s%s" % (
                            prefix, basename), ext=ext))

            vol = load_vol(vol) if not is_niimg(vol) else vol

            nibabel.save(vol, output_filename)

            # update rvols and filenames
            filenames.append(output_filename)

    return filenames
Ejemplo n.º 54
0
    def _run_interface(self, runtime):
        from dipy.reconst.peaks import peaks_from_model
        from dipy.tracking.eudx import EuDX
        from dipy.data import get_sphere
        # import marshal as pickle
        import pickle as pickle
        import gzip

        if (not (isdefined(self.inputs.in_model)
                 or isdefined(self.inputs.in_peaks))):
            raise RuntimeError(('At least one of in_model or in_peaks should '
                                'be supplied'))

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.affine

        data = img.get_data().astype(np.float32)
        hdr = imref.header.copy()
        hdr.set_data_dtype(np.float32)
        hdr['data_type'] = 16

        sphere = get_sphere('symmetric724')

        self._save_peaks = False
        if isdefined(self.inputs.in_peaks):
            IFLOGGER.info('Peaks file found, skipping ODF peaks search...')
            f = gzip.open(self.inputs.in_peaks, 'rb')
            peaks = pickle.load(f)
            f.close()
        else:
            self._save_peaks = True
            IFLOGGER.info('Loading model and computing ODF peaks')
            f = gzip.open(self.inputs.in_model, 'rb')
            odf_model = pickle.load(f)
            f.close()

            peaks = peaks_from_model(
                model=odf_model,
                data=data,
                sphere=sphere,
                relative_peak_threshold=self.inputs.peak_threshold,
                min_separation_angle=self.inputs.min_angle,
                parallel=self.inputs.multiprocess)

            f = gzip.open(self._gen_filename('peaks', ext='.pklz'), 'wb')
            pickle.dump(peaks, f, -1)
            f.close()

        hdr.set_data_shape(peaks.gfa.shape)
        nb.Nifti1Image(peaks.gfa.astype(np.float32), affine, hdr).to_filename(
            self._gen_filename('gfa'))

        IFLOGGER.info('Performing tractography')

        if isdefined(self.inputs.tracking_mask):
            msk = nb.load(self.inputs.tracking_mask).get_data()
            msk[msk > 0] = 1
            msk[msk < 0] = 0
        else:
            msk = np.ones(imref.shape)

        gfa = peaks.gfa * msk
        seeds = self.inputs.num_seeds

        if isdefined(self.inputs.seed_coord):
            seeds = np.loadtxt(self.inputs.seed_coord)

        elif isdefined(self.inputs.seed_mask):
            seedmsk = nb.load(self.inputs.seed_mask).get_data()
            assert (seedmsk.shape == data.shape[:3])
            seedmsk[seedmsk > 0] = 1
            seedmsk[seedmsk < 1] = 0
            seedps = np.array(np.where(seedmsk == 1), dtype=np.float32).T
            vseeds = seedps.shape[0]
            nsperv = (seeds // vseeds) + 1
            IFLOGGER.info('Seed mask is provided (%d voxels inside '
                          'mask), computing seeds (%d seeds/voxel).', vseeds,
                          nsperv)
            if nsperv > 1:
                IFLOGGER.info('Needed %d seeds per selected voxel (total %d).',
                              nsperv, vseeds)
                seedps = np.vstack(np.array([seedps] * nsperv))
                voxcoord = seedps + np.random.uniform(-1, 1, size=seedps.shape)
                nseeds = voxcoord.shape[0]
                seeds = affine.dot(
                    np.vstack((voxcoord.T, np.ones((1, nseeds)))))[:3, :].T

                if self.inputs.save_seeds:
                    np.savetxt(self._gen_filename('seeds', ext='.txt'), seeds)

        if isdefined(self.inputs.tracking_mask):
            tmask = msk
            a_low = 0.1
        else:
            tmask = gfa
            a_low = self.inputs.gfa_thresh

        eu = EuDX(
            tmask,
            peaks.peak_indices[..., 0],
            seeds=seeds,
            affine=affine,
            odf_vertices=sphere.vertices,
            a_low=a_low)

        ss_mm = [np.array(s) for s in eu]

        trkfilev = nb.trackvis.TrackvisFile(
            [(s, None, None) for s in ss_mm],
            points_space='rasmm',
            affine=np.eye(4))
        trkfilev.to_file(self._gen_filename('tracked', ext='.trk'))
        return runtime
print('')
print("Shape of permutation data:")

for s in range(nsubj):
    print(dat[s].shape)

print('')

end = timer()
print("Data loaded: {seconds:.4f} seconds".format(seconds=end-start))
middle = timer()

if args.mask:
    try:
        mask_img = nib.four_to_three(nib.load(args.mask))[0]
    except ValueError:
        mask_img = nib.load(args.mask)

    mask_data = mask_img.get_data()
    # If it is a probability map of tissue types, this says treat all voxels
    # that have a probability 0.2 or higher of being grey matter.
    # 0.2 is based on John Ashburner's VBM tutorial (VBMclass15.pdf) and Kurth,
    # Gaser, and Luders (2015, Nature Protocols)
    print("Masking reference data ...")
    try:
        mask = (mask_data > 0.2) * automask
    except:
        print("Dimension mismatch between mask and data! Resampling the mask and trying again ...")
        rmask = nib.processing.resample_from_to(mask_img, reference_img)
        mask_data = rmask.get_data()
    def _run_interface(self, runtime):
        if len(self.inputs.in_files) > 1:
            iflogger.info('Multiple input images detected')
            iflogger.info(len(self.inputs.in_files))
            in_files = self.inputs.in_files
        elif isdefined(self.inputs.in_file4d):
            iflogger.info('Single four-dimensional image selected')
            in_file4d = nb.load(self.inputs.in_file4d)
            in_files = nb.four_to_three(in_file4d)
        else:
            iflogger.info('Single functional image provided')
            in_files = self.inputs.in_files

        if len(in_files) == 1:
            iflogger.error(
                "Only one functional image was input. Pearson's correlation coefficient can not be calculated")
            raise ValueError
        else:
            rois = get_roi_list(self.inputs.segmentation_file)
            fMRI_timecourse = get_timecourse_by_region(
                in_files, self.inputs.segmentation_file, rois)

        timecourse_at_each_node = fMRI_timecourse.T
        iflogger.info(np.shape(timecourse_at_each_node))
        iflogger.info(
            'Structural Network: {s}'.format(s=self.inputs.structural_network))
        structural_network = nx.read_gpickle(self.inputs.structural_network)
        rois = structural_network.nodes()
        #rois = get_roi_list(self.inputs.segmentation_file)
        number_of_nodes = len(rois)
        iflogger.info('Found {roi} unique region values'.format(roi=len(rois)))

        newntwk = structural_network.copy()
        newntwk = remove_all_edges(newntwk)

        simple_correlation_matrix = np.zeros(
            (number_of_nodes, number_of_nodes))
        iflogger.info('Drawing edges...')
        for idx_i, roi_i in enumerate(rois):
            #iflogger.info('ROI:{i}, T-value: {t}'.format(i=roi_i, t=t_i))
            for idx_j, roi_j in enumerate(rois):
                #iflogger.info('...ROI:{j}, T-value: {t}'.format(j=roi_j, t=t_j))
                if idx_j > idx_i:
                    simple_correlation_matrix[idx_i, idx_j] = pearsonr(
                        fMRI_timecourse[idx_i], fMRI_timecourse[idx_j])[0]
                elif roi_i == roi_j:
                    simple_correlation_matrix[idx_i, idx_j] = 0.5

        simple_correlation_matrix = simple_correlation_matrix + \
            simple_correlation_matrix.T
        stats = {'correlation': simple_correlation_matrix}
        newntwk = add_edge_data(simple_correlation_matrix, newntwk)
        path, name, ext = split_filename(self.inputs.out_network_file)
        if not ext == '.pck':
            ext = '.pck'
        out_network_file = op.abspath(name + ext)
        iflogger.info(
            'Saving simple correlation network as {out}'.format(out=out_network_file))
        nx.write_gpickle(newntwk, out_network_file)

        path, name, ext = split_filename(self.inputs.out_stats_file)
        if not ext == '.mat':
            ext = '.mat'
        out_stats_file = op.abspath(name + ext)

        iflogger.info(
            'Saving image statistics as {stats}'.format(stats=out_stats_file))
        sio.savemat(out_stats_file, stats)
        return runtime
    def _run_interface(self, runtime):
        if isdefined(self.inputs.lookup_table):
            LUT_dict = get_names(self.inputs.lookup_table)
                    
        if len(self.inputs.in_files) > 1:
            iflogger.info('Multiple input images detected')
            iflogger.info(len(self.inputs.in_files))
            in_files = self.inputs.in_files
        elif isdefined(self.inputs.in_file4d):
            iflogger.info('Single four-dimensional image selected')
            in_files = nb.four_to_three(self.inputs.in_file4d)
        else:
            iflogger.info('Single functional image provided')
            in_files = self.inputs.in_files

        per_file_stats = {}
        seg_file = nb.load(self.inputs.segmentation_file)
        segmentationdata = seg_file.get_data()

        if isdefined(self.inputs.resolution_network_file):
            try:
                gp = nx.read_gpickle(self.inputs.resolution_network_file)
            except:
                gp = nx.read_graphml(self.inputs.resolution_network_file)
            nodedict = gp.node[gp.nodes()[0]]
            if not nodedict.has_key('dn_position'):
                iflogger.info("Creating node positions from segmentation")
                G = nx.Graph()
                for u, d in gp.nodes_iter(data=True):
                    iflogger.info('Node ID {id}'.format(id=int(u)))
                    G.add_node(int(u), d)
                    xyz = tuple(
                        np.mean(np.where(np.flipud(segmentationdata) == int(d["dn_correspondence_id"])), axis=1))
                    G.node[int(u)]['dn_position'] = xyz
                ntwkname = op.abspath('nodepositions.pck')
                nx.write_gpickle(G, ntwkname)
            else:
                ntwkname = self.inputs.resolution_network_file

            rois = get_roi_list(self.inputs.segmentation_file)
            roi_mean_tc, roi_max_tc, roi_min_tc, roi_std_tc, voxels = get_timecourse_by_region(
                in_files, self.inputs.segmentation_file, rois)

            stats = {}
            stats['func_max'] = roi_max_tc
            stats['func_mean'] = roi_mean_tc
            stats['func_min'] = roi_min_tc
            stats['func_stdev'] = roi_std_tc
            stats['number_of_voxels'] = voxels
            stats['rois'] = rois
            if isdefined(self.inputs.lookup_table):
                stats['roi_names'] = []
                for x in rois:
                    try:
                        stats['roi_names'].append(LUT_dict[x])
                    except KeyError:
                        stats['roi_names'].append("Unknown_ROI_" + str(x))

            global all_ntwks
            all_ntwks = list()
            for in_file_idx, in_file in enumerate(in_files):
                ntwks = list()
                per_file_stats = {}
                per_file_stats['func_max'] = roi_max_tc[:, in_file_idx]
                per_file_stats['func_mean'] = roi_mean_tc[:, in_file_idx]
                per_file_stats['func_min'] = roi_min_tc[:, in_file_idx]
                per_file_stats['func_stdev'] = roi_std_tc[:, in_file_idx]
                per_file_stats['rois'] = rois
                if isdefined(self.inputs.lookup_table):
                    per_file_stats['roi_names'] = [LUT_dict[x] for x in rois]
                #per_file_stats['number_of_voxels'] = voxels[in_file_idx]
                for key in per_file_stats.keys():
                    iflogger.info(key)
                    iflogger.info(np.shape(per_file_stats[key]))
                    try:
                        nwtk = nx.read_gpickle(ntwkname)
                        newntwk = add_node_data(per_file_stats[key], nwtk)
                    except:
                        iflogger.error(key)
                        iflogger.error(np.shape(per_file_stats[key]))
                        iflogger.error(
                            "Double-check the subjects' freesurfer directory.")

                        raise Exception(
                            "There may not be enough regions in the segmentation file!")

                    name = '{k}_{i}'.format(k=key, i=str(in_file_idx))
                    out_file = op.abspath(name + '.pck')
                    nx.write_gpickle(newntwk, out_file)
                    ntwks.append(out_file)
                all_ntwks.extend(ntwks)
        else:
            rois = get_roi_list(self.inputs.segmentation_file)
            roi_mean_tc, roi_max_tc, roi_min_tc, roi_std_tc, voxels = get_timecourse_by_region(
                in_files, self.inputs.segmentation_file, rois)

            stats = {}
            stats['func_max'] = roi_max_tc
            stats['func_mean'] = roi_mean_tc
            stats['func_min'] = roi_min_tc
            stats['func_stdev'] = roi_std_tc
            stats['number_of_voxels'] = voxels
            stats['rois'] = rois
            if isdefined(self.inputs.lookup_table):
                stats['roi_names'] = []
                for x in rois:
                    try:
                        stats['roi_names'].append(LUT_dict[x])
                    except KeyError:
                        stats['roi_names'].append("Unknown_ROI_" + str(x))

        if isdefined(self.inputs.subject_id):
            stats['subject_id'] = self.inputs.subject_id

        out_stats_file = op.abspath(self.inputs.out_stats_file)
        iflogger.info(
            'Saving image statistics as {stats}'.format(stats=out_stats_file))
        sio.savemat(out_stats_file, stats)
        return runtime
Ejemplo n.º 58
0
def save_vols(vols,
              output_dir,
              basenames=None,
              affine=None,
              concat=False,
              prefix='',
              ext=None):
    """
    Saves a single 4D image or a couple of 3D vols unto disk.

    vols: single 4D nibabel image object, or list of 3D nibabel image objects
        volumes, of ndarray
        volumes to be saved

    output_dir: string
        existing filename, destination directory

    basenames: string or list of string, optional (default None)
        basename(s) for output image(s)

    affine: 2D array of shape (4, 4)
        affine matrix for the output images

    concat: bool, optional (default False)
        concatenate all vols into a single film

    prefix: string, optional (default '')
       prefix to be prepended to output file basenames

    ext: string, optional (default ".nii.gz")
        file extension for output images

    Returns
    -------
    string of list of strings, dependending on whether vols is list or
    not, and on whether concat is set or not
        the output image filename(s)

    """
    if ext is None:
        ext = ".nii.gz"

    def _nifti_or_ndarray_to_nifti(x):
        if is_niimg(x):
            if affine is not None:
                raise ValueError(
                    ("vol is of type %s; not expecting `affine` parameter.") %
                    type(x))
            else:
                return x

        if affine is None:
            raise ValueError(
                "vol is of type ndarray; you need to specifiy `affine`")
        else:
            return nibabel.Nifti1Image(x, affine)

    if basenames is not None:
        basenames = get_basenames(basenames, ext=ext)

    # sanitize output_dir
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # vols are ndarray ?
    if isinstance(vols, np.ndarray):
        vols = _nifti_or_ndarray_to_nifti(vols)

    # concat vols to single 4D film ?
    if concat:
        if isinstance(vols, list):
            vols = nibabel.concat_images(
                [_nifti_or_ndarray_to_nifti(vol) for vol in vols],
                check_affines=False)
            if basenames is not None:
                if not isinstance(basenames, _basestring):
                    basenames = basenames[0]
        else:
            if basenames is not None:
                if not isinstance(basenames, _basestring):
                    raise RuntimeError(
                        ("concat=True specified but basenames is of type %s "
                         "instead of string") % type(basenames))

    if not isinstance(vols, list):
        if basenames is None:
            basenames = get_basenames("vols", ext=ext)

        if not isinstance(basenames, _basestring):
            vols = nibabel.four_to_three(vols)
            filenames = []
            for vol, basename in zip(vols, basenames):
                if not isinstance(basename, _basestring):
                    raise RuntimeError
                filename = os.path.join(output_dir,
                                        "%s%s" % (prefix, basename))
                nibabel.save(vol, filename)
                filenames.append(filename)
        else:
            filenames = os.path.join(output_dir, "%s%s" % (prefix, basenames))
            nibabel.save(vols, filenames)

        return filenames
    else:
        n_vols = len(vols)
        filenames = []
        if basenames is None:
            if prefix:
                prefix = prefix + "_"
        else:
            if isinstance(basenames, _basestring):
                basenames = [
                    "vol%i_%s" % (t, basenames) for t in range(len(vols))
                ]
            else:
                if len(set(basenames)) != len(vols):
                    raise RuntimeError
        for t, vol in zip(range(n_vols), vols):
            if isinstance(vol, np.ndarray):
                if affine is None:
                    raise ValueError(
                        ("vols is of type ndarray; you need to specifiy"
                         " `affine`"))
                else:
                    vol = nibabel.Nifti1Image(vol, affine)

            # save realigned vol unto disk
            if basenames is None:
                output_filename = os.path.join(
                    output_dir, get_basename("%svol_%i" % (prefix, t),
                                             ext=ext))
            else:
                basename = basenames if isinstance(
                    basenames, _basestring) else basenames[t]
                output_filename = os.path.join(
                    output_dir,
                    get_basenames("%s%s" % (prefix, basename), ext=ext))

            vol = check_niimg(vol)
            nibabel.save(vol, output_filename)

            # update rvols and filenames
            filenames.append(output_filename)

    return filenames
Ejemplo n.º 59
0
    def _run_interface(self, runtime):
        data_dir = op.abspath('./denoise/components')
        if not os.path.exists(data_dir):
            os.makedirs(data_dir)

        in_files = self.inputs.in_files
        if len(self.inputs.in_files) > 1:
            print 'Multiple ({n}) input images detected! Copying to {d}...'.format(n=len(self.inputs.in_files), d=data_dir)
            for in_file in self.inputs.in_files:
                path, name, ext = split_filename(in_file)
                shutil.copyfile(in_file, op.join(data_dir, name) + ext)
                if ext == '.img':
                    shutil.copyfile(op.join(path, name) + '.hdr',
                                    op.join(data_dir, name) + '.hdr')
                elif ext == '.hdr':
                    shutil.copyfile(op.join(path, name) + '.img',
                                    op.join(data_dir, name) + '.img')
            print 'Copied!'
            in_files = self.inputs.in_files

        elif isdefined(self.inputs.in_file4d):
            print 'Single four-dimensional image selected. Splitting and copying to {d}'.format(d=data_dir)
            in_files = nb.four_to_three(self.inputs.in_file4d)
            for in_file in in_files:
                path, name, ext = split_filename(in_file)
                shutil.copyfile(in_file, op.join(data_dir, name) + ext)
            print 'Copied!'

        else:
            print 'Single functional image provided. Ending...'
            in_files = self.inputs.in_files

        nComponents = len(in_files)
        path, name, ext = split_filename(self.inputs.time_course_image)
        shutil.copyfile(self.inputs.time_course_image,
                        op.join(data_dir, name) + ext)

        if ext == '.img':
            shutil.copyfile(op.join(path, name) + '.hdr',
                            op.join(data_dir, name) + '.hdr')
        elif ext == '.hdr':
            shutil.copyfile(op.join(path, name) + '.img',
                            op.join(data_dir, name) + '.img')

        data_dir = op.abspath('./denoise')
        path, name, ext = split_filename(self.inputs.ica_mask_image)
        shutil.copyfile(self.inputs.ica_mask_image,
                        op.join(data_dir, name) + ext)
        if ext == '.img':
            shutil.copyfile(op.join(path, name) + '.hdr',
                            op.join(data_dir, name) + '.hdr')
        elif ext == '.hdr':
            shutil.copyfile(op.join(path, name) + '.img',
                            op.join(data_dir, name) + '.img')
        mask_file = op.join(data_dir, name)
        repetition_time = self.inputs.repetition_time
        neuronal_image = op.abspath(self.inputs.out_neuronal_image)
        non_neuronal_image = op.abspath(self.inputs.out_non_neuronal_image)
        coma_rest_lib_path = op.abspath(self.inputs.coma_rest_lib_path)
        d = dict(
            data_dir=data_dir, mask_name=mask_file, nComponents=nComponents, Tr=repetition_time,
            nameNeuronal=neuronal_image, nameNonNeuronal=non_neuronal_image, coma_rest_lib_path=coma_rest_lib_path)
        script = Template("""
        restlib_path = '$coma_rest_lib_path';
        setup_restlib_paths(restlib_path)
        dataDir = '$data_dir';
        maskName = '$mask_name';
        nCompo = $nComponents;
        Tr = $Tr;
        nameNeuronalData = '$nameNeuronal';
        nameNonNeuronalData = '$nameNonNeuronal';
        denoiseImage(dataDir,maskName,nCompo,Tr,nameNeuronalData,nameNonNeuronalData, restlib_path);
        """).substitute(d)
        result = MatlabCommand(script=script, mfile=True,
                               prescript=[''], postscript=[''])
        r = result.run()
        print 'Neuronal component image saved as {n}'.format(n=neuronal_image)
        print 'Non-neuronal component image saved as {n}'.format(n=non_neuronal_image)
        return runtime
Ejemplo n.º 60
0
    def _run_interface(self, runtime):
        from dipy.core.gradients import GradientTable
        from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity
        from dipy.reconst.csdeconv import recursive_response, auto_response

        img = nb.load(self.inputs.in_file)
        imref = nb.four_to_three(img)[0]
        affine = img.affine

        if isdefined(self.inputs.in_mask):
            msk = nb.load(self.inputs.in_mask).get_data()
            msk[msk > 0] = 1
            msk[msk < 0] = 0
        else:
            msk = np.ones(imref.shape)

        data = img.get_data().astype(np.float32)
        gtab = self._get_gradient_table()

        evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data())
        FA = np.nan_to_num(fractional_anisotropy(evals)) * msk
        indices = np.where(FA > self.inputs.fa_thresh)
        S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]]
        S0 = np.mean(S0s)

        if self.inputs.auto:
            response, ratio = auto_response(gtab, data,
                                            roi_radius=self.inputs.roi_radius,
                                            fa_thr=self.inputs.fa_thresh)
            response = response[0].tolist() + [S0]
        elif self.inputs.recursive:
            MD = np.nan_to_num(mean_diffusivity(evals)) * msk
            indices = np.logical_or(
                FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))
            data = nb.load(self.inputs.in_file).get_data()
            response = recursive_response(gtab, data, mask=indices, sh_order=8,
                                          peak_thr=0.01, init_fa=0.08,
                                          init_trace=0.0021, iter=8,
                                          convergence=0.001,
                                          parallel=True)
            ratio = abs(response[1] / response[0])
        else:
            lambdas = evals[indices]
            l01 = np.sort(np.mean(lambdas, axis=0))

            response = np.array([l01[-1], l01[-2], l01[-2], S0])
            ratio = abs(response[1] / response[0])

        if ratio > 0.25:
            IFLOGGER.warn('Estimated response is not prolate enough. '
                          'Ratio=%0.3f.', ratio)
        elif ratio < 1.e-5 or np.any(np.isnan(response)):
            response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0])
            IFLOGGER.warn('Estimated response is not valid, using a default one')
        else:
            IFLOGGER.info('Estimated response: %s', str(response[:3]))

        np.savetxt(op.abspath(self.inputs.response), response)

        wm_mask = np.zeros_like(FA)
        wm_mask[indices] = 1
        nb.Nifti1Image(
            wm_mask.astype(np.uint8), affine,
            None).to_filename(op.abspath(self.inputs.out_mask))
        return runtime