code: def diffusion_components(
      dki_params, sphere="repulsion100", awf=None, mask=None
  ):
      """Extracts the restricted and hindered diffusion tensors of well aligned
      fibers from diffusion kurtosis imaging parameters [1]_.
  
      Parameters
      ----------
      dki_params : ndarray (x, y, z, 27) or (n, 27)
          All parameters estimated from the diffusion kurtosis model.
          Parameters are ordered as follows:
              1) Three diffusion tensor's eigenvalues
              2) Three lines of the eigenvector matrix each containing the first,
                 second and third coordinates of the eigenvector
              3) Fifteen elements of the kurtosis tensor
      sphere : Sphere class instance, optional
          The sphere providing sample directions to sample the restricted and
          hindered cellular diffusion tensors. For more details see Fieremans
          et al., 2011.
      awf : ndarray (optional)
          Array containing values of the axonal water fraction that has the shape
          dki_params.shape[:-1]. If not given this will be automatically computed
          using :func:`axonal_water_fraction`" with function's default precision.
      mask : ndarray (optional)
          A boolean array used to mark the coordinates in the data that should be
          analyzed that has the shape dki_params.shape[:-1]
  
      Returns
      -------
      edt : ndarray (x, y, z, 6) or (n, 6)
          Parameters of the hindered diffusion tensor.
      idt : ndarray (x, y, z, 6) or (n, 6)
          Parameters of the restricted diffusion tensor.
  
      Notes
      -----
      In the original article of DKI microstructural model [1]_, the hindered and
      restricted tensors were defined as the intra-cellular and extra-cellular
      diffusion compartments respectively.
  
      References
      ----------
      .. [1] Fieremans E, Jensen JH, Helpern JA, 2011. White matter
             characterization with diffusional kurtosis imaging.
             Neuroimage 58(1):177-88. doi: 10.1016/j.neuroimage.2011.06.006
      """
      shape = dki_params.shape[:-1]
  
      # load gradient directions
      if not isinstance(sphere, dps.Sphere):
          sphere = get_sphere(sphere)
  
      # select voxels where to apply the single fiber model
      if mask is None:
          mask = np.ones(shape, dtype="bool")
      else:
          if mask.shape != shape:
              raise ValueError(
                  "Mask is not the same shape as dki_params."
              )
          else:
              mask = np.array(mask, dtype=bool, copy=False)
  
      # check or compute awf values
      if awf is None:
          awf = axonal_water_fraction(
              dki_params, sphere=sphere, mask=mask
          )
      else:
          if awf.shape != shape:
              raise ValueError(
                  "awf array is not the same shape as dki_params."
              )
  
      # Initialize hindered and restricted diffusion tensors
      edt_all = np.zeros(shape + (6,))
      idt_all = np.zeros(shape + (6,))
  
      # Generate matrix that converts apparent diffusion coefficients to tensors
      B = np.zeros((sphere.x.size, 6))
      B[:, 0] = sphere.x * sphere.x  # Bxx
      B[:, 1] = sphere.x * sphere.y * 2.0  # Bxy
      B[:, 2] = sphere.y * sphere.y  # Byy
      B[:, 3] = sphere.x * sphere.z * 2.0  # Bxz
      B[:, 4] = sphere.y * sphere.z * 2.0  # Byz
      B[:, 5] = sphere.z * sphere.z  # Bzz
      pinvB = np.linalg.pinv(B)
  
      # Compute hindered and restricted diffusion tensors for all voxels
      evals, evecs, kt = split_dki_param(dki_params)
      dt = lower_triangular(vec_val_vect(evecs, evals))
      md = mean_diffusivity(evals)
  
      index = ndindex(mask.shape)
      for idx in index:
          if not mask[idx]:
              continue
          # sample apparent diffusion and kurtosis values
          di = directional_diffusion(dt[idx], sphere.vertices)
          ki = directional_kurtosis(
              dt[idx],
              md[idx],
              kt[idx],
              sphere.vertices,
              adc=di,
              min_kurtosis=0,
          )
          edi = di * (
              1 + np.sqrt(ki * awf[idx] / (3.0 - 3.0 * awf[idx]))
          )
          edt = np.dot(pinvB, edi)
          edt_all[idx] = edt
  
          # We only move on if there is an axonal water fraction.
          # Otherwise, remaining params are already zero, so move on
          if awf[idx] == 0:
              continue
          # Convert apparent diffusion and kurtosis values to apparent diffusion
          # values of the hindered and restricted diffusion
          idi = di * (
              1 - np.sqrt(ki * (1.0 - awf[idx]) / (3.0 * awf[idx]))
          )
          # generate hindered and restricted diffusion tensors
          idt = np.dot(pinvB, idi)
          idt_all[idx] = idt
  
      return edt_all, idt_all
  
imports: import numpy
  from dipy.reconst.dti import lower_triangular, from_lower_triangular, decompose_tensor, trace, mean_diffusivity, radial_diffusivity, axial_diffusivity, MIN_POSITIVE_SIGNAL
  from dipy.reconst.dki import split_dki_param, _positive_evals, directional_kurtosis, directional_diffusion, kurtosis_maximum, DiffusionKurtosisModel, DiffusionKurtosisFit
  from dipy.reconst.dti import design_matrix
  from dipy.core.ndindex import ndindex
  from dipy.reconst.vec_val_sum import vec_val_vect
  from dipy.data import get_sphere
  import dipy.core.sphere
label_desc: Use image node_id 2 for calling a global function with example usage: diffusion_components(dki_params, sphere, awf, mask) and returns: edt_all,  idt_all