code: def test_reorient_bvecs(rng):
      sq2 = np.sqrt(2) / 2
      bvals = np.concatenate([[0], np.ones(6) * 1000])
      bvecs = np.array(
          [
              [0, 0, 0],
              [1, 0, 0],
              [0, 1, 0],
              [0, 0, 1],
              [sq2, sq2, 0],
              [sq2, 0, sq2],
              [0, sq2, sq2],
          ]
      )
  
      gt = gradient_table_from_bvals_bvecs(bvals, bvecs, b0_threshold=0)
      # The simple case: all affines are identity
      affs = np.zeros((4, 4, 6))
      for i in range(4):
          affs[i, i, :] = 1
  
      # We should get back the same b-vectors
      new_gt = reorient_bvecs(gt, affs)
      npt.assert_equal(gt.bvecs, new_gt.bvecs)
  
      # Now apply some rotations
      rotation_affines = []
      rotated_bvecs = bvecs[:]
      for i in np.where(~gt.b0s_mask)[0]:
          rot_ang = rng.random()
          cos_rot = np.cos(rot_ang)
          sin_rot = np.sin(rot_ang)
          rotation_affines.append(
              np.array(
                  [
                      [1, 0, 0, 0],
                      [0, cos_rot, -sin_rot, 0],
                      [0, sin_rot, cos_rot, 0],
                      [0, 0, 0, 1],
                  ]
              )
          )
          rotated_bvecs[i] = np.dot(
              rotation_affines[-1][:3, :3], bvecs[i]
          )
  
      rotation_affines = np.stack(rotation_affines, axis=-1)
      # Copy over the rotation affines
      full_affines = rotation_affines[:]
      # And add some scaling and translation to each one to make this harder
      for i in range(full_affines.shape[-1]):
          full_affines[..., i] = np.dot(
              full_affines[..., i],
              np.array(
                  [
                      [2.5, 0, 0, -10],
                      [0, 2.2, 0, 20],
                      [0, 0, 1, 0],
                      [0, 0, 0, 1],
                  ]
              ),
          )
  
      gt_rot = gradient_table_from_bvals_bvecs(
          bvals, rotated_bvecs, b0_threshold=0
      )
      new_gt = reorient_bvecs(gt_rot, full_affines)
      # At the end of all this, we should be able to recover the original
      # vectors
      npt.assert_almost_equal(gt.bvecs, new_gt.bvecs)
  
      # We should be able to pass just the 3-by-3 rotation components to the same
      # effect
      new_gt = reorient_bvecs(
          gt_rot, np.array(rotation_affines)[:3, :3]
      )
      npt.assert_almost_equal(gt.bvecs, new_gt.bvecs)
  
      # Verify that giving the wrong number of affines raises an error:
      full_affines = np.concatenate(
          [full_affines, np.zeros((4, 4, 1))], axis=-1
      )
      npt.assert_raises(
          ValueError, reorient_bvecs, gt_rot, full_affines
      )
  
      # Shear components in the matrix need to be decomposed into rotation only,
      # and should not lead to scaling of the bvecs
      shear_affines = []
      for i in np.where(~gt.b0s_mask)[0]:
          shear_affines.append(
              np.array(
                  [
                      [1, 0, 1, 0],
                      [0, 1, 0, 0],
                      [0, 0, 1, 0],
                      [0, 0, 0, 1],
                  ]
              )
          )
      shear_affines = np.stack(shear_affines, axis=-1)
      # atol is set to 1 here to do the scaling verification here,
      # so that the reorient_bvecs function does not throw an error itself
      new_gt = reorient_bvecs(gt, shear_affines[:3, :3], atol=1)
      bvecs_close_to_1 = (
          abs(vector_norm(new_gt.bvecs[~gt.b0s_mask]) - 1) <= 0.001
      )
      npt.assert_(np.all(bvecs_close_to_1))
  
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 13 for calling a global function with example usage: test_reorient_bvecs(rng) without return types