code: def forward_sdt_deconv_mat(ratio, n, r2_term=False):
      r"""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.0,
                  1.0,
              )
          else:
              sharp = quad(
                  lambda z: lpn(l, z)[0][-1]
                  * np.sqrt(1 / (1 - (1 - ratio) * z * z)),
                  -1.0,
                  1.0,
              )
  
          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)
  
imports: import warnings
  import numpy
  import numbers
  from scipy.integrate import quad
  from scipy.special import lpn, gamma
  import scipy.linalg
  import scipy.linalg.lapack
  from dipy.data import small_sphere, get_sphere, default_sphere
  from dipy.core.geometry import cart2sphere
  from dipy.core.ndindex import ndindex
  from dipy.sims.voxel import single_tensor
  from dipy.reconst.multi_voxel import multi_voxel_fit
  from dipy.reconst.dti import TensorModel, fractional_anisotropy
  from dipy.reconst.shm import sph_harm_ind_list, real_sh_descoteaux_from_index, sph_harm_lookup, lazy_index, SphHarmFit, real_sh_descoteaux, sh_to_rh, forward_sdeconv_mat, SphHarmModel
  from dipy.reconst.utils import _roi_in_volume, _mask_from_roi
  from dipy.direction.peaks import peaks_from_model
  from dipy.core.geometry import vec2vec_rotmat
  from dipy.utils.deprecator import deprecate_with_version, deprecated_params
label_desc: Use image node_id 4 for calling a global function with example usage: forward_sdt_deconv_mat(ratio, n, r2_term) and returns: np,  np