Example #1
0
def test_unique_bvals_magnitude():
    bvals = np.array([1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 0])
    ubvals_gt = np.array([0, 1000, 2000])
    b = unique_bvals_magnitude(bvals)
    npt.assert_array_almost_equal(ubvals_gt, b)

    bvals = np.array([995, 995, 995, 995, 2005, 2005, 2005, 2005, 0])
    # Case that b-values are rounded:
    b = unique_bvals_magnitude(bvals)
    npt.assert_array_almost_equal(ubvals_gt, b)

    # b-values are not rounded if you specific the magnitude of the values
    # precision:
    b = unique_bvals_magnitude(bvals, bmag=0)
    npt.assert_array_almost_equal(b, np.array([0, 995, 2005]))

    # Case that b-values are in ms/um2
    bvals = np.array(
        [0.995, 0.995, 0.995, 0.995, 2.005, 2.005, 2.005, 2.005, 0])
    b = unique_bvals_magnitude(bvals)
    ubvals_gt = np.array([0, 1, 2])
    npt.assert_array_almost_equal(ubvals_gt, b)

    # Test case that optional parameter round_bvals is set to true
    bvals = np.array([995, 1000, 1004, 1000, 2001, 2000, 1988, 2017, 0])
    ubvals_gt = np.array([0, 1000, 2000])
    rbvals_gt = np.array([1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 0])
    ub, rb = unique_bvals_magnitude(bvals, rbvals=True)
    npt.assert_array_almost_equal(ubvals_gt, ub)
    npt.assert_array_almost_equal(rbvals_gt, rb)
Example #2
0
def test_design_matrix():
    ub = unique_bvals_magnitude(bvals_3s)
    D = msdki.design_matrix(ub)
    Dgt = np.ones((4, 3))
    Dgt[:, 0] = -ub
    Dgt[:, 1] = 1.0 / 6 * ub**2
    assert_array_almost_equal(D, Dgt)
Example #3
0
    def __init__(self, gtab, bmag=None, return_S0_hat=False, *args, **kwargs):
        """ Mean Signal Diffusion Kurtosis Model [1]_.

        Parameters
        ----------
        gtab : GradientTable class instance

        bmag : int
            The order of magnitude that the bvalues have to differ to be
            considered an unique b-value. Default: derive this value from the
            maximal b-value provided: $bmag=log_{10}(max(bvals)) - 1$.

        return_S0_hat : bool
            If True, also return S0 values for the fit.

        args, kwargs : arguments and keyword arguments passed to the
        fit_method. See msdki.wls_fit_msdki for details

        References
        ----------
        .. [1] Henriques, R.N., 2018. Advanced Methods for Diffusion MRI Data
               Analysis and their Application to the Healthy Ageing Brain
               (Doctoral thesis). Downing College, University of Cambridge.
               https://doi.org/10.17863/CAM.29356

        """
        ReconstModel.__init__(self, gtab)

        self.return_S0_hat = return_S0_hat
        self.ubvals = unique_bvals_magnitude(gtab.bvals, bmag=bmag)
        self.design_matrix = design_matrix(self.ubvals)
        self.bmag = bmag
        self.args = args
        self.kwargs = kwargs
        self.min_signal = self.kwargs.pop('min_signal', MIN_POSITIVE_SIGNAL)
        if self.min_signal is not None and self.min_signal <= 0:
            e_s = "The `min_signal` key-word argument needs to be strictly"
            e_s += " positive."
            raise ValueError(e_s)

        # Check if at least three b-values are given
        enough_b = check_multi_b(self.gtab, 3, non_zero=False, bmag=bmag)
        if not enough_b:
            mes = "MSDKI requires at least 3 b-values (which can include b=0)"
            raise ValueError(mes)
Example #4
0
def test_msdki_statistics():
    # tests if MD and MK are equal to expected values of a spherical
    # tensors

    # Multi-tensors
    ub = unique_bvals_magnitude(bvals_3s)
    design_matrix = msdki.design_matrix(ub)
    msignal, ng = msdki.mean_signal_bvalue(DWI, gtab_3s, bmag=None)
    params = msdki.wls_fit_msdki(design_matrix, msignal, ng)
    assert_array_almost_equal(params[..., 1], MKgt_multi)
    assert_array_almost_equal(params[..., 0], MDgt_multi)

    mdkiM = msdki.MeanDiffusionKurtosisModel(gtab_3s)
    mdkiF = mdkiM.fit(DWI)
    mk = mdkiF.msk
    md = mdkiF.msd
    assert_array_almost_equal(MKgt_multi, mk)
    assert_array_almost_equal(MDgt_multi, md)

    # Single-tensors
    mdkiF = mdkiM.fit(signal_sph)
    mk = mdkiF.msk
    md = mdkiF.msd
    assert_array_almost_equal(MKgt, mk)
    assert_array_almost_equal(MDgt, md)

    # Test with given mask
    mask = np.ones(DWI.shape[:-1])
    v = (0, 0, 0)
    mask[1, 1, 1] = 0
    mdkiF = mdkiM.fit(DWI, mask=mask)
    mk = mdkiF.msk
    md = mdkiF.msd
    assert_array_almost_equal(MKgt_multi, mk)
    assert_array_almost_equal(MDgt_multi, md)
    assert_array_almost_equal(MKgt_multi[v], mdkiF[v].msk)  # tuple case
    assert_array_almost_equal(MDgt_multi[v], mdkiF[v].msd)  # tuple case
    assert_array_almost_equal(MKgt_multi[0], mdkiF[0].msk)  # not tuple case
    assert_array_almost_equal(MDgt_multi[0], mdkiF[0].msd)  # not tuple case

    # Test returned S0
    mdkiM = msdki.MeanDiffusionKurtosisModel(gtab_3s, return_S0_hat=True)
    mdkiF = mdkiM.fit(DWI)
    assert_array_almost_equal(S0gt_multi, mdkiF.S0_hat)
    assert_array_almost_equal(MKgt_multi[v], mdkiF[v].msk)
Example #5
0
def mean_signal_bvalue(data, gtab, bmag=None):
    """
    Computes the average signal across different diffusion directions
    for each unique b-value

    Parameters
    ----------
    data : ndarray ([X, Y, Z, ...], g)
        ndarray containing the data signals in its last dimension.
    gtab : a GradientTable class instance
        The gradient table containing diffusion acquisition parameters.
    bmag : The order of magnitude that the bvalues have to differ to be
        considered an unique b-value. Default: derive this value from the
        maximal b-value provided: $bmag=log_{10}(max(bvals)) - 1$.

    Returns
    -------
    msignal : ndarray ([X, Y, Z, ..., nub])
        Mean signal along all gradient directions for each unique b-value
        Note that the last dimension contains the signal means and nub is the
        number of unique b-values.
    ng : ndarray(nub)
        Number of gradient directions used to compute the mean signal for
        all unique b-values

    Notes
    -----
    This function assumes that directions are evenly sampled on the sphere or
    on the hemisphere
    """
    bvals = gtab.bvals.copy()

    # Compute unique and rounded bvals
    ub, rb = unique_bvals_magnitude(bvals, bmag=bmag, rbvals=True)

    # Initialize msignal and ng
    nub = ub.size
    ng = np.zeros(nub)
    msignal = np.zeros(data.shape[:-1] + (nub,))
    for bi in range(ub.size):
        msignal[..., bi] = np.mean(data[..., rb == ub[bi]], axis=-1)
        ng[bi] = np.sum(rb == ub[bi])
    return msignal, ng