code: def test_btens_to_params(rng):
      """
      Checks if bvals, bdeltas and b_etas are as expected for 4 b-tensor shapes
      (LTE, PTE, STE, CTE) as well as scaled and rotated versions of them
  
      This function intrinsically tests the function `_btens_to_params_2d` as
      `_btens_to_params_2d` is only meant to be called by `btens_to_params`
  
      """
      n_rotations = 30
      n_scales = 3
  
      expected_bvals = np.array([1, 1, 1, 1])
      expected_bdeltas = np.array([1, -0.5, 0, 0.5])
      expected_b_etas = np.array([0, 0, 0, 0])
  
      # Baseline tensors to test
      linear_tensor = np.array([[1, 0, 0], [0, 0, 0], [0, 0, 0]])
      planar_tensor = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1]]) / 2
      spherical_tensor = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) / 3
      cigar_tensor = np.array([[2, 0, 0], [0, 0.5, 0], [0, 0, 0.5]]) / 3
  
      base_tensors = [
          linear_tensor,
          planar_tensor,
          spherical_tensor,
          cigar_tensor,
      ]
  
      # ---------------------------------
      # Test function on baseline tensors
      # ---------------------------------
  
      # Loop through each tensor type and check results
      for i, tensor in enumerate(base_tensors):
          i_bval, i_bdelta, i_b_eta = btens_to_params(tensor)
  
          npt.assert_array_almost_equal(i_bval, expected_bvals[i])
          npt.assert_array_almost_equal(i_bdelta, expected_bdeltas[i])
          npt.assert_array_almost_equal(i_b_eta, expected_b_etas[i])
  
      # Test function on a 3D input
      base_tensors_array = np.empty((4, 3, 3))
      base_tensors_array[0, :, :] = linear_tensor
      base_tensors_array[1, :, :] = planar_tensor
      base_tensors_array[2, :, :] = spherical_tensor
      base_tensors_array[3, :, :] = cigar_tensor
  
      bvals, bdeltas, b_etas = btens_to_params(base_tensors_array)
  
      npt.assert_array_almost_equal(bvals, expected_bvals)
      npt.assert_array_almost_equal(bdeltas, expected_bdeltas)
      npt.assert_array_almost_equal(b_etas, expected_b_etas)
  
      # -----------------------------------------------------
      # Test function after rotating+scaling baseline tensors
      # -----------------------------------------------------
  
      scales = np.concatenate((np.array([1]), rng.random(n_scales)))
  
      for scale in scales:
          ebs = expected_bvals * scale
  
          # Generate `n_rotations` random 3-element vectors of norm 1
          v = rng.random((n_rotations, 3)) - 0.5
          u = np.apply_along_axis(
              lambda w: w / np.linalg.norm(w), axis=1, arr=v
          )
  
          for rot_idx in range(n_rotations):
              # Get rotation matrix for current iteration
              u_i = u[rot_idx, :]
              R_i = vec2vec_rotmat(np.array([1, 0, 0]), u_i)
  
              # Rotate each of the baseline test tensors and check results
              for i, tensor in enumerate(base_tensors):
                  tensor_rot_i = np.matmul(
                      np.matmul(R_i, tensor), R_i.T
                  )
                  i_bval, i_bdelta, i_b_eta = btens_to_params(
                      tensor_rot_i * scale
                  )
  
                  npt.assert_array_almost_equal(i_bval, ebs[i])
                  npt.assert_array_almost_equal(
                      i_bdelta, expected_bdeltas[i]
                  )
                  npt.assert_array_almost_equal(
                      i_b_eta, expected_b_etas[i]
                  )
  
      # Input can't be string
      npt.assert_raises(ValueError, btens_to_params, "LTE")
  
      # Input can't be list of strings
      npt.assert_raises(ValueError, btens_to_params, ["LTE", "LTE"])
  
      # Input can't be 1D nor 4D
      npt.assert_raises(ValueError, btens_to_params, np.zeros((3,)))
      npt.assert_raises(
          ValueError, btens_to_params, np.zeros((3, 3, 3, 3))
      )
  
      # Input shape must be (3, 3) OR (N, 3, 3)
      npt.assert_raises(ValueError, btens_to_params, np.zeros((4, 4)))
      npt.assert_raises(
          ValueError, btens_to_params, np.zeros((2, 2, 2))
      )
  
imports: import warnings
  import numpy
  import numpy.testing
  import pytest
  from dipy.data import get_fnames
  from dipy.core.gradients import b0_threshold_empty_gradient_message, b0_threshold_update_slicing_message, gradient_table, GradientTable, gradient_table_from_bvals_bvecs, gradient_table_from_qvals_bvecs, gradient_table_from_gradient_strength_bvecs, WATER_GYROMAGNETIC_RATIO, mask_non_weighted_bvals, orientation_to_string, reorient_bvecs, generate_bvecs, check_multi_b, round_bvals, get_bval_indices, unique_bvals_magnitude, unique_bvals_tolerance, unique_bvals, params_to_btens, btens_to_params, orientation_from_string, reorient_vectors
  from dipy.core.geometry import vec2vec_rotmat, vector_norm
  from dipy.io.gradients import read_bvals_bvecs
  from dipy.utils.deprecator import ExpiredDeprecationError
  from dipy.testing import clear_and_catch_warnings
  from dipy.testing.decorators import set_random_number_generator
label_desc: Use image node_id 22 for calling a global function with example usage: test_btens_to_params(rng) without return types