Ejemplo n.º 1
0
def forward_sdt_deconv_mat(ratio, n):
    """ Build forward sharpening deconvolution transform (SDT) matrix

    Parameters
    ----------
    ratio : float
        ratio = $\frac{\lambda_2}{\lambda_1}$ of the single fiber response function
    n : ndarray (N,)
        The degree of spherical harmonic function associated with each row of
        the deconvolution matrix. Only even degrees are allowed.

    Returns
    -------
    R : ndarray (N, N)
        SDT deconvolution matrix
    P : ndarray (N, N)
        Funk-Radon Transform (FRT) matrix

    """
    if np.any(n % 2):
        raise ValueError("n has odd degrees, expecting only even degrees")
    n_degrees = n.max() // 2 + 1
    sdt = np.zeros(n_degrees) # SDT matrix
    frt = np.zeros(n_degrees) # FRT (Funk-Radon transform) q-ball matrix

    for l in np.arange(0, n_degrees*2, 2):
        sharp = quad(lambda z: lpn(l, z)[0][-1] * np.sqrt(1 / (1 - (1 - ratio) * z * z)), -1., 1.)

        sdt[l / 2] = sharp[0]
        frt[l / 2] = 2 * np.pi * lpn(l, 0)[0][-1]

    idx = n // 2
    b = sdt[idx]
    bb = frt[idx]
    return np.diag(b), np.diag(bb)
Ejemplo n.º 2
0
def forward_sdt_deconv_mat(ratio, n, r2_term=False):
    """ Build forward sharpening deconvolution transform (SDT) matrix

    Parameters
    ----------
    ratio : float
        ratio = $\frac{\lambda_2}{\lambda_1}$ of the single fiber response
        function
    n : ndarray (N,)
        The degree of spherical harmonic function associated with each row of
        the deconvolution matrix. Only even degrees are allowed.
    r2_term : bool
        True if ODF comes from an ODF computed from a model using the $r^2$
        term in the integral. For example, DSI, GQI, SHORE, CSA, Tensor,
        Multi-tensor ODFs. This results in using the proper analytical response
        function solution solving from the single-fiber ODF with the r^2 term.
        This derivation is not published anywhere but is very similar to [1]_.

    Returns
    -------
    R : ndarray (N, N)
        SDT deconvolution matrix
    P : ndarray (N, N)
        Funk-Radon Transform (FRT) matrix

    References
    ----------
    .. [1] Descoteaux, M. PhD Thesis. INRIA Sophia-Antipolis. 2008.

    """
    if np.any(n % 2):
        raise ValueError("n has odd degrees, expecting only even degrees")
    n_degrees = n.max() // 2 + 1
    sdt = np.zeros(n_degrees)  # SDT matrix
    frt = np.zeros(n_degrees)  # FRT (Funk-Radon transform) q-ball matrix

    for l in np.arange(0, n_degrees * 2, 2):
        if r2_term:
            sharp = quad(lambda z: lpn(l, z)[0][-1] * gamma(1.5) *
                         np.sqrt(ratio / (4 * np.pi ** 3)) /
                         np.power((1 - (1 - ratio) * z ** 2), 1.5), -1., 1.)
        else:
            sharp = quad(lambda z: lpn(l, z)[0][-1] *
                         np.sqrt(1 / (1 - (1 - ratio) * z * z)), -1., 1.)

        sdt[l // 2] = sharp[0]
        frt[l // 2] = 2 * np.pi * lpn(l, 0)[0][-1]

    idx = n // 2
    b = sdt[idx]
    bb = frt[idx]
    return np.diag(b), np.diag(bb)
Ejemplo n.º 3
0
    def __init__(self, gtab, sh_order, smooth=0, min_signal=1.,
                 assume_normed=False):
        """Creates a model that can be used to fit or sample diffusion data

        Arguments
        ---------
        gtab : GradientTable
            Diffusion gradients used to acquire data
        sh_order : even int >= 0
            the spherical harmonic order of the model
        smoothness : float between 0 and 1
            The regularization parameter of the model
        assume_normed : bool
            If True, data will not be normalized before fitting to the model

        """
        m, n = sph_harm_ind_list(sh_order)
        self._where_b0s = lazy_index(gtab.b0s_mask)
        self._where_dwi = lazy_index(~gtab.b0s_mask)
        self.assume_normed = assume_normed
        self.min_signal = min_signal
        x, y, z = gtab.gradients[self._where_dwi].T
        r, theta, phi = cart2sphere(x, y, z)
        B = real_sph_harm(m, n, theta[:, None], phi[:, None])
        L = -n * (n + 1)
        legendre0 = lpn(sh_order, 0)[0]
        F = legendre0[n]
        self.B = B
        self.m = m
        self.n = n
        self._set_fit_matrix(B, L, F, smooth)
Ejemplo n.º 4
0
 def cf(theta):
     nmax = 10000
     nmin = 1
     larr = np.arange(nmin,nmax+1).astype(np.float64)
     pl = lpn(nmax, np.cos(theta))[0][nmin:]
     
     return ((2*larr+1.0)*pl*self.angular_ps(larr)).sum() / (4*np.pi)
Ejemplo n.º 5
0
    def __init__(self, data, sh_order, grad_table, b_values, smoothness=0,
                 keep_resid=False):
        if (sh_order % 2 != 0 or sh_order < 0 ):
            raise ValueError('sh_order must be an even integer >= 0')
        self.sh_order = sh_order
        dwi = b_values > 0
        self.ngrad = dwi.sum()

        R, theta, phi = cartesian2polar(grad_table[dwi, 0], grad_table[dwi, 0],
                                        grad_table[dwi, 2])

        m_list, n_list = sph_harm_ind_list(self.sh_order)
        if m_list.size > self.ngrad:
            raise ValueError('sh_order seems too high, there are only '+
                str(self.ngrad)+' diffusion weighted images in data')
        design_mat = real_sph_harm(m_list, n_list, theta, phi)
        
        if smoothness == 0:
            self.fit_matrix = np.linalg.pinv(design_mat)
        else:
            L = np.diag(n_list*(n_list+1))*sqrt(smoothness)
            self.fit_matrix = np.linalg.pinv(np.c_[design_mat, L])[:,:self.ngrad]
        legendre0, junk = lpn(self.sh_order, 0)
        funk_radon = legendre0[n_list]
        self.fit_matrix *= funk_radon.T

        self.b0 = data[..., np.logical_not(dwi)]
        self._coef = np.dot(data[..., dwi], self.fit_matrix)

        if keep_resid:
            unfit = design_mat / funk_radon
            self._resid = data[..., dwi] - np.dot(self._coef, unfit)
        else:
            self._resid = None
Ejemplo n.º 6
0
    def __init__(self, data, sh_order, grad_table, b_values, keep_resid=False):
        if (sh_order % 2 != 0 or sh_order < 0 ):
            raise ValueError('sh_order must be an even integer >= 0')
        self.sh_order = sh_order
        dwi = b_values > 0
        self.ngrad = dwi.sum()

        theta = np.arctan2(grad_table[1, dwi], grad_table[0, dwi])
        phi = np.arccos(grad_table[2, dwi])

        m_list, n_list = sph_harm_ind_list(self.sh_order)
        if m_list.size > self.ngrad:
            raise ValueError('sh_order seems too high, there are only '+
            str(self.ngrad)+' diffusion weighted images in data')
        comp_mat = real_sph_harm(m_list, n_list, theta, phi)

        self.fit_matrix = np.linalg.pinv(comp_mat)
        legendre0, junk = lpn(self.sh_order, 0)
        funk_radon = legendre0[n_list]
        self.fit_matrix *= funk_radon.T

        self.b0 = data[..., np.logical_not(dwi)]
        self._coef = np.dot(data[..., dwi], self.fit_matrix)

        if keep_resid:
            unfit = comp_mat / funk_radon
            self._resid = data[..., dwi] - np.dot(self._coef, unfit)
        else:
            self._resid = None
Ejemplo n.º 7
0
def gaussLegQuadSet(sNords):
    """
    Input number of ordinates. (should be even number)
    Compute symetric gauss-leg quadrature set
    """
    legWeights = np.zeros(sNords + 1)
    pnp1s = np.zeros(sNords)
    pprimes = np.zeros(sNords)
    legWeights[sNords] = 1.
    mus = np.polynomial.legendre.legroots(legWeights)
    for i, mu in enumerate(mus):
        pprimes[i] = spc.lpn(sNords, mu)[1][-1]
        pnp1s[i] = spc.lpn(sNords + 1, mu)[0][-1]
    weights = -2. / ((sNords + 1) * pnp1s * pprimes)
    #
    ordinateSet = np.array([mus[::-1], weights])
    return ordinateSet
Ejemplo n.º 8
0
 def init_shifts(self,shifts,k0):
     self.shifts = shifts
     self.theta = arange(0, pi, 0.05)
     f_l = (exp(2j*shifts)-1)/(2j*k0)
     for t in self.theta:
         f=0.0
         for l in range(shifts.size):
             f = f + (2*l+1)*f_l[l]*lpn(l,cos(t))[0][l]
         self.dcs.append(abs(f)[0]**2)
Ejemplo n.º 9
0
def forward_sdt_deconv_mat(ratio, sh_order):
    """ Build forward sharpening deconvolution transform (SDT) matrix

    Parameters
    ----------
    ratio : float
        ratio = $\frac{\lambda_2}{\lambda_1}$ of the single fiber response function
    sh_order : int
        spherical harmonic order

    Returns
    -------
    R : ndarray (``(sh_order + 1)*(sh_order + 2)/2``, ``(sh_order + 1)*(sh_order + 2)/2``)
        SDT deconvolution matrix
    P : ndarray (``(sh_order + 1)*(sh_order + 2)/2``, ``(sh_order + 1)*(sh_order + 2)/2``)
        Funk-Radon Transform (FRT) matrix
    """
    m, n = sph_harm_ind_list(sh_order)

    sdt = np.zeros(m.shape) # SDT matrix
    frt = np.zeros(m.shape) # FRT (Funk-Radon transform) q-ball matrix
    b = np.zeros(m.shape)
    bb = np.zeros(m.shape)

    for l in np.arange(0, sh_order + 1, 2):
        from scipy.integrate import quad
        sharp = quad(lambda z: lpn(l, z)[0][-1] * np.sqrt(1 / (1 - (1 - ratio) * z * z)), -1., 1.)

        sdt[l / 2] = sharp[0]
        frt[l / 2] = 2 * np.pi * lpn(l, 0)[0][-1]

    i = 0
    for l in np.arange(0, sh_order + 1, 2):
        for m in np.arange(-l, l + 1):
            b[i] = sdt[l / 2]
            bb[i] = frt[l / 2]
            i = i + 1

    return np.diag(b), np.diag(bb)
Ejemplo n.º 10
0
def GetWeight(idump=1,nvar=8,nmax=5,type='vx'):
    data=rd_dumses.DumsesData(idump,nvar)
    vx=data.get_1d_y(type)
    nz=data.y.size
    Pn=np.zeros((nz,nmax+1))
    In=np.zeros(nmax+1)
    ciso=1.e-3 ; Omega0=1.e-3 ; H=ciso/Omega0 ; Lz=10.*H
    dz=Lz/nz

    if type in ('vx','vz'):
        for n in range(1,nmax+1):
            for k in range(nz):
                Pn[k,n]=lpn(n,np.tanh(data.y[k]))[0][n]
                In[n]=In[n]+vx[k]*Pn[k,n]*(1.-np.tanh(data.y[k])**2)*dz
            In[n]=(2*n+1)/2.*In[n]
    else:
        for n in range(1,nmax+1):
            for k in range(nz):
                Pn[k,n]=lpn(n,np.tanh(data.y[k]))[1][n]
                In[n]=In[n]+vx[k]*Pn[k,n]*(1.-np.tanh(data.y[k])**2)*dz
            In[n]=(2*n+1)/2./n/(n+1)*In[n]

    return In
Ejemplo n.º 11
0
def AssociatedLegendreP(l,m,alpha):
    """
    Returns polynomial P_l^m for (l=0, ... l) for the given m.
    """
    from scipy.special import lpn
    import numpy as np
    from numpy import cos, sin

    dat = lpn(l, cos(alpha))  # Pl, and d(Pl)/dx
    LegPol = dat[0]
    dLdx = dat[1]  # 0,1,2,... l

    # dLdx is in dimension: 0,1,2,...l
    np.zeros((l+1))
    #return (-1)**m * sin(alpha) * dLdx # 0,1,2,...l for the given m.
    return (-1)**m * (sin(alpha))**abs(m) * dLdx
Ejemplo n.º 12
0
    def __init__(self, gtab, sh_order, smooth=0.006, min_signal=1.,
                 assume_normed=False):
        """Creates a model that can be used to fit or sample diffusion data

        Arguments
        ---------
        gtab : GradientTable
            Diffusion gradients used to acquire data
        sh_order : even int >= 0
            the spherical harmonic order of the model
        smooth : float between 0 and 1, optional
            The regularization parameter of the model
        min_signal : float, > 0, optional
            During fitting, all signal values less than `min_signal` are
            clipped to `min_signal`. This is done primarily to avoid values
            less than or equal to zero when taking logs.
        assume_normed : bool, optional
            If True, clipping and normalization of the data with respect to the
            mean B0 signal are skipped during mode fitting. This is an advanced
            feature and should be used with care.

        See Also
        --------
        normalize_data

        """
        SphHarmModel.__init__(self, gtab)
        self._where_b0s = lazy_index(gtab.b0s_mask)
        self._where_dwi = lazy_index(~gtab.b0s_mask)
        self.assume_normed = assume_normed
        self.min_signal = min_signal
        x, y, z = gtab.gradients[self._where_dwi].T
        r, theta, phi = cart2sphere(x, y, z)
        B, m, n = real_sym_sh_basis(sh_order, theta[:, None], phi[:, None])
        L = -n * (n + 1)
        legendre0 = lpn(sh_order, 0)[0]
        F = legendre0[n]
        self.sh_order = sh_order
        self.B = B
        self.m = m
        self.n = n
        self._set_fit_matrix(B, L, F, smooth)
Ejemplo n.º 13
0
def calc_R_X(kas, phi, n):
    R = np.zeros(kas.shape)
    X = np.zeros(kas.shape)
    kas_2 = kas**2
    cos_phi = np.cos(phi)

    P = lpn(n, cos_phi)[0]

    for m in np.arange(n):
        P_p = P[m + 1]
        if m == 0:
            P_n = 1.0 # from Morse-1968
        else:
            P_n = P[m - 1]

        jn_p = spherical_jn(m + 1, kas)
        if m > 0:
            jn_n = spherical_jn(m - 1, kas)
        else:
            jn_n = np.zeros(kas.shape)
        yn_p = spherical_yn(m + 1, kas)
        if m > 0:
            yn_n = spherical_yn(m - 1, kas)
        else:
            yn_n = np.zeros(kas.shape)

        B = ((1.0 / (2.0 * m + 1.0))
             * np.sqrt((m * yn_n - (m + 1) * yn_p)**2
                       + ((m + 1) * jn_p - m * jn_n)**2))
        delta = np.arctan2((m + 1) * jn_p - m * jn_n,
                           m * yn_n - (m + 1) * yn_p)

        R += (P_n - P_p)**2 / (kas_2 * (2.0 * m + 1.0) * (B * np.sin(phi * 0.5))**2)

        X += (((P_n - P_p)**2 / ((2.0 * m + 1.0) * B * np.sin(phi * 0.5)**2))
              * (spherical_jn(m, kas) * np.sin(delta) - spherical_yn(m, kas) * np.cos(delta)))

    return 0.25 * R, 0.25 * X
Ejemplo n.º 14
0
    def __init__(self, bval, gradients, sh_order, smooth=0,
                 odf_vertices=None, odf_edges=None):
        """Creates a model that can be used to fit or sample diffusion data

        Arguments
        ---------
        bval : ndarray (n,)
            the b values for the data, where n is the number of volumes in data
        gradient : ndarray (n, 3)
            the diffusing weighting gradient directions for the data, n is the
            number of volumes in the data
        sh_order : even int >= 0
            the spherical harmonic order of the model
        smoothness : float between 0 and 1
            The regulization peramater of the model
        odf_vertices : ndarray (v, 3), optional
            Points on a unit sphere, used to evaluate odf
        odf_edges : ndarray (e, 2), dtype=int16, optional
            A list of Neighboring vertices

        """
        m, n = sph_harm_ind_list(sh_order)
        where_dwi = bval > 0
        self._index = (Ellipsis, lazy_index(where_dwi))
        x, y, z = gradients[where_dwi].T
        r, pol, azi = cart2sphere(x, y, z)
        B = real_sph_harm(m, n, azi[:, None], pol[:, None])
        L = -n*(n+1)
        legendre0 = lpn(sh_order, 0)[0]
        F = legendre0[n]
        self.B = B
        self._m = m
        self._n = n
        self._set_fit_matrix(B, L, F, smooth)
        if odf_vertices is not None:
            self.set_odf_vertices(odf_vertices, odf_edges)
Ejemplo n.º 15
0
def analytic_cov(coeffs, cos_mu, lmax=1000):
    """
    Evaluate the covariance function 

                  inf
                  ---
    C(cos(mu)) := \   (2l+1) C_l P_l (cos(mu)) / 4 pi
                  /
                  ---
                  l=0

    """

    # Make the C_l from the Markov coefficients
    C_l = make_cl(coeffs, lmax)
    # Coeffs excluding legendre poly, i.e. C_l * (2l+1) / 4 pi
    l_coeffs = C_l * (2 * arange(lmax + 1) + 1) * (0.25 / pi)

    correl = zeros(len(cos_mu))
    for i, z in enumerate(cos_mu):
        Plz, dPlz_dz = lpn(lmax, z)  # Legendre polys and their derivs
        correl[i] = inner(Plz, l_coeffs)

    return correl
Ejemplo n.º 16
0
 def uBoundaryNeumannTrace(self, point):
     x, y, z = point
     r = np.sqrt(x**2 + y**2 + z**2)
     Y, dY = lpn(self.l_max, x / r)
     val = (self.aInc * self.cBound * Y).sum()
     return val
Ejemplo n.º 17
0
 def uExactSquaredBoundaryNeumannTrace(self, point, normal, domain_index, result):
     x, y, z = point
     n_x, n_y, n_z = normal
     r = np.sqrt(x**2 + y**2 + z**2)
     Y, dY = lpn(self.l_max, x / r)
     result[0] = (self.cBoundSq * Y).sum()
Ejemplo n.º 18
0
else:
    Lrange = range(Lmax + 1)
    jl, dj = sph_jn(Lrange, k*a, False), sph_jn(Lrange, k*a, True) # (j_l, j_l')
    nl, dn = sph_yn(Lrange, k*a, False), sph_yn(Lrange, k*a, True) # (n_l, n_l')

for L in range(Lmax+1):
    u, g = wf(M, a)                     # g= u'/u
    x = np.arctan(((g*a-1)*jl[L] - k*a*dj[L])/    # phase shift 
                  ((g*a-1)*nl[L] - k*a*dn[L]))
    while (x < 0.0): x += np.pi         # handle jumps by pi 
    ps[L] = x

theta, sigma = np.linspace(0., np.pi, 100), []
cos, La = np.cos(theta), np.arange(1,2*Lmax+2,2)
for x in cos:                               # calc cross section
    pl = lpn(Lmax, x)[0]                    # Legendre polynomial 
    fl = La*np.exp(1j*ps)*np.sin(ps)*pl     # amplitude 
    sigma.append(np.abs(np.sum(fl))**2/(k*k))
        
plt.figure()                                # plot phase shift vs L
plt.plot(range(Lmax+1), ps, '-o')
plt.xlabel('$l$'), plt.ylabel(r'$\delta_l$', fontsize=16)

plt.figure()        
plt.plot(theta*180/np.pi, sigma)            # plot cross sections   
xtck = [0, 30, 60, 90, 120, 150, 180]
plt.xticks(xtck, [repr(i) for i in xtck])   # custom ticks 
plt.xlabel(r'$\theta$ (deg)')
plt.ylabel(r'$\sigma(\theta)$ (a.u.)'), plt.semilogy()

plt.show()
Ejemplo n.º 19
0
 def uExactDirichletTrace(self, point):
     x, y, z = point
     r = np.sqrt(x**2 + y**2 + z**2)
     hD, dhD = sph_jn(self.l_max, self.kExt * r) + 1j*sph_yn(self.l_max, self.kExt * r)
     Y, dY = lpn(self.l_max, x / r)
     return (self.cDir * hD * Y).sum()
Ejemplo n.º 20
0
 def uExactNeumannTrace(self, point):
     x, y, z = point
     r = np.sqrt(x**2 + y**2 + z**2)
     Y, dY = lpn(self.l_max, x / r)
     val = (self.aInc * self.cBound * Y).sum()
     return val
Ejemplo n.º 21
0
 def uExactBoundaryNeumannTrace(self, point, normal, domain_index, result):
     x, y, z = point
     n_x, n_y, n_z = normal
     r = np.sqrt(x**2 + y**2 + z**2)
     Y, dY = lpn(self.l_max, x / r)
     result[0] = (self.aInc * self.cBound * Y).sum()
Ejemplo n.º 22
0
def lpn_(n, x):
    return lpn(n.astype("l"), x)[0][-1]
Ejemplo n.º 23
0
def Pl_func (x, l) :
    """Compute Pl(x).  This routine is NOT optimized."""
    (pl, dpl) = sf.lpn (l, x)
    return pl[l]
Ejemplo n.º 24
0
k, ps = np.sqrt(2 * E), np.zeros(Lmax + 1)  # wave vector, phase shift
jl, dj = sph_jn(Lmax, k * a)  # (j_l, j_l') tuple
nl, dn = sph_yn(Lmax, k * a)  # (n_l, n_l')

for L in range(Lmax + 1):
    u, g = wf(M, a)  # g= u'/u
    x = np.arctan(((g * a - 1) * jl[L] - k * a * dj[L]) /  # phase shift 
                  ((g * a - 1) * nl[L] - k * a * dn[L]))
    while (x < 0.0):
        x += np.pi  # handle jumps by pi
    ps[L] = x

theta, sigma = np.linspace(0., np.pi, 100), []
cos, La = np.cos(theta), np.arange(1, 2 * Lmax + 2, 2)
for x in cos:  # calc cross section
    pl = lpn(Lmax, x)[0]  # Legendre polynomial
    fl = La * np.exp(1j * ps) * np.sin(ps) * pl  # amplitude
    sigma.append(np.abs(np.sum(fl))**2 / (k * k))

plt.figure()  # plot phase shift vs L
plt.plot(range(Lmax + 1), ps, '-o')
plt.xlabel('$l$'), plt.ylabel(r'$\delta_l$', fontsize=16)

plt.figure()
plt.plot(theta * 180 / np.pi, sigma)  # plot cross sections
xtck = [0, 30, 60, 90, 120, 150, 180]
plt.xticks(xtck, [repr(i) for i in xtck])  # custom ticks
plt.xlabel(r'$\theta$ (deg)')
plt.ylabel(r'$\sigma(\theta)$ (a.u.)'), plt.semilogy()

plt.show()
Ejemplo n.º 25
0
def afd_and_rd_sums_along_streamlines(sft, fodf, fodf_basis, length_weighting):
    """
    Compute the mean Apparent Fiber Density (AFD) and mean Radial fODF (radfODF)
    maps along a bundle.

    Parameters
    ----------
    sft : StatefulTractogram
        StatefulTractogram containing the streamlines needed.
    fodf : nibabel.image
        fODF with shape (X, Y, Z, #coeffs).
        #coeffs depend on the sh_order.
    fodf_basis : string
        Has to be descoteaux07 or tournier07.
    length_weighting : bool
        If set, will weigh the AFD values according to segment lengths.

    Returns
    -------
    afd_sum_map : np.array
        AFD map.
    rd_sum_map : np.array
        fdAFD map.
    weight_map : np.array
        Segment lengths.
    """

    sft.to_vox()
    sft.to_corner()

    fodf_data = np.asanyarray(fodf.dataobj)
    order = find_order_from_nb_coeff(fodf_data)
    sphere = get_sphere('repulsion724')
    b_matrix, _, n = get_b_matrix(order, sphere, fodf_basis, return_all=True)
    legendre0_at_n = lpn(order, 0)[0][n]
    sphere_norm = np.linalg.norm(sphere.vertices)

    afd_sum_map = np.zeros(shape=fodf_data.shape[:-1])
    rd_sum_map = np.zeros(shape=fodf_data.shape[:-1])
    weight_map = np.zeros(shape=fodf_data.shape[:-1])

    p_matrix = np.eye(fodf_data.shape[3]) * legendre0_at_n
    all_crossed_indices = grid_intersections(sft.streamlines)
    for crossed_indices in all_crossed_indices:
        segments = crossed_indices[1:] - crossed_indices[:-1]
        seg_lengths = np.linalg.norm(segments, axis=1)

        # Remove points where the segment is zero.
        # This removes numpy warnings of division by zero.
        non_zero_lengths = np.nonzero(seg_lengths)[0]
        segments = segments[non_zero_lengths]
        seg_lengths = seg_lengths[non_zero_lengths]

        test = np.dot(segments, sphere.vertices.T)
        test2 = (test.T / (seg_lengths * sphere_norm)).T
        angles = np.arccos(test2)
        sorted_angles = np.argsort(angles, axis=1)
        closest_vertex_indices = sorted_angles[:, 0]

        # Those starting points are used for the segment vox_idx computations
        strl_start = crossed_indices[non_zero_lengths]
        vox_indices = (strl_start + (0.5 * segments)).astype(int)

        normalization_weights = np.ones_like(seg_lengths)
        if length_weighting:
            normalization_weights = seg_lengths / np.linalg.norm(
                fodf.header.get_zooms()[:3])

        for vox_idx, closest_vertex_index, norm_weight in zip(
                vox_indices, closest_vertex_indices, normalization_weights):
            vox_idx = tuple(vox_idx)
            b_at_idx = b_matrix[closest_vertex_index]
            fodf_at_index = fodf_data[vox_idx]

            afd_val = np.dot(b_at_idx, fodf_at_index)
            rd_val = np.dot(np.dot(b_at_idx.T, p_matrix), fodf_at_index)

            afd_sum_map[vox_idx] += afd_val * norm_weight
            rd_sum_map[vox_idx] += rd_val * norm_weight
            weight_map[vox_idx] += norm_weight

    rd_sum_map[rd_sum_map < 0.] = 0.

    return afd_sum_map, rd_sum_map, weight_map
Ejemplo n.º 26
0
def lpn_(n, x):
    return lpn(n.astype('l'), x)[0][-1]
Ejemplo n.º 27
0
def ModesConstruct(idump=0,nrange=(0,10),nmode=0,nvar=8,type='vx',save=0):
    
    if nmode==0:
        if size(nrange)==1:
            nmodes=nrange
        else:
            nmodes=nrange[0]+np.array(range(nrange[1]-nrange[0]+1))
    if nmode==1:
        nmodes=np.array(nrange)

    #Get Data
    data=rd_dumses.DumsesData(idump,nvar)
    vx=data.get_1d_y(type)
    rho=data.get_1d_y('rho')
    if (type=='bx'):
        by=data.get_1d_y('by')
    else:
        by=1
    nz=data.y.size

    #Get Normal modes amplitudes
    if size(nmodes)==1:
        In=GetWeight(idump=idump,nmax=nmodes,type=type)
    else:
        In=GetWeight(idump=idump,nmax=max(nmodes),type=type)
    Mode=np.zeros(nz)

    #Reconstruct modes
    if size(nmodes)==1:
        mode_nb=nmodes
        if type in ('vx','vz'):
            for k in range(nz):
                z=np.tanh(data.y[k])
                Mode[k]=In[mode_nb]*lpn(mode_nb,z)[0][mode_nb]
        else:
            for k in range(nz):
                z=np.tanh(data.y[k])
                Mode[k]=In[mode_nb]*lpn(mode_nb,z)[1][mode_nb]*(1-z**2)
    else:        
        if type in ('vx','vz'):
            for n in range(size(nmodes)):
                mode_nb=nmodes[n]
                for k in range(nz):
                    z=np.tanh(data.y[k])
                    Mode[k]=Mode[k]+In[mode_nb]*lpn(mode_nb,z)[0][mode_nb]
        else:
            for n in range(size(nmodes)):
                mode_nb=nmodes[n]
                for k in range(nz):
                    z=np.tanh(data.y[k])
                    Mode[k]=Mode[k]+In[mode_nb]*lpn(mode_nb,z)[1][mode_nb]*(1-z**2)
    #Conv2beta
    #vx=conv2beta(vx,exp(-data.y**2/2.))
    #Mode=conv2beta(Mode,exp(-data.y**2/2.))

    #Plot results
    axes=Axes(figure(1),[0.25,0.25,0.5,0.5])
    xlabel('z/H') ; ylabel('Bx/Bz')
    plot(data.y,vx/by,linewidth=2.5,linestyle='-',color='b')
    plot(data.y,Mode/by,linewidth=2,linestyle='--',color='r')
    xlim((min(data.y),max(data.y)))
    subplots_adjust(left=0.15)
    #show()
    #ylim((0,30))
    if save==1:
        savefig('mode_'+type+'.eps')