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)
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)
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)
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)
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
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
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
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)
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)
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
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
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)
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
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)
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
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
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()
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()
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()
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
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()
def lpn_(n, x): return lpn(n.astype("l"), x)[0][-1]
def Pl_func (x, l) : """Compute Pl(x). This routine is NOT optimized.""" (pl, dpl) = sf.lpn (l, x) return pl[l]
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()
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
def lpn_(n, x): return lpn(n.astype('l'), x)[0][-1]
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')