code: def test_peak_directions_thorough():
      # two equal fibers (creating a very sharp odf)
      mevals = np.array(
          [[0.0025, 0.0003, 0.0003], [0.0025, 0.0003, 0.0003]]
      )
      angles = [(0, 0), (45, 0)]
      fractions = [50, 50]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # two unequal fibers
      fractions = [75, 25]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 1, 2)
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.20, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # two equal fibers short angle (simulating very sharp ODF)
      mevals = np.array(
          ([0.0045, 0.0003, 0.0003], [0.0045, 0.0003, 0.0003])
      )
      fractions = [50, 50]
      angles = [(0, 0), (20, 0)]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 1, 2)
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 15.0
      )
  
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # 1 fiber
      mevals = np.array(
          [[0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003]]
      )
      fractions = [50, 50]
      angles = [(15, 0), (15, 0)]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 15.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 1, 2)
  
      AE = np.rad2deg(np.arccos(np.dot(directions[0], sticks[0])))
      assert_(abs(AE) < 2.0 or abs(AE - 180) < 2.0)
  
      # two equal fibers and one small noisy one
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (90, 0)]
      fractions = [45, 45, 10]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # two equal fibers and one faulty
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (60, 0)]
      fractions = [45, 45, 10]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # two equal fibers and one very very annoying one
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (60, 0)]
      fractions = [40, 40, 20]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 2, 2)
  
      # three peaks and one faulty
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (90, 0), (90, 45)]
      fractions = [35, 35, 20, 10]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 3, 2)
  
      # four peaks
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (90, 0), (90, 45)]
      fractions = [25, 25, 25, 25]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.15, 5.0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 4, 2)
  
      # four difficult peaks
      mevals = np.array(
          [
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
              [0.0015, 0.0003, 0.0003],
          ]
      )
      angles = [(0, 0), (45, 0), (90, 0), (90, 45)]
      fractions = [30, 30, 20, 20]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0, 0
      )
      assert_almost_equal(angular_similarity(directions, sticks), 4, 1)
  
      # test the asymmetric case
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0, 0, False
      )
      expected = np.concatenate([sticks, -sticks], axis=0)
      assert_almost_equal(
          angular_similarity(directions, expected), 8, 1
      )
  
      odf_gt, sticks, hsphere = _create_mt_sim(
          mevals, angles, fractions, 100, None, half_sphere=True
      )
  
      directions, values, indices = peak_directions(
          odf_gt, hsphere, 0, 0
      )
      assert_equal(angular_similarity(directions, sticks) < 4, True)
  
      # four peaks and one them quite small
      fractions = [35, 35, 20, 10]
  
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0, 0
      )
      assert_equal(angular_similarity(directions, sticks) < 4, True)
  
      odf_gt, sticks, hsphere = _create_mt_sim(
          mevals, angles, fractions, 100, None, half_sphere=True
      )
  
      directions, values, indices = peak_directions(
          odf_gt, hsphere, 0, 0
      )
      assert_equal(angular_similarity(directions, sticks) < 4, True)
  
      # isotropic case
      mevals = np.array([[0.0015, 0.0015, 0.0015]])
      angles = [(0, 0)]
      fractions = [100.0]
      odf_gt, sticks, sphere = _create_mt_sim(
          mevals, angles, fractions, 100, None
      )
  
      directions, values, indices = peak_directions(
          odf_gt, sphere, 0.5, 25.0
      )
      assert_equal(len(values) > 10, True)
  
imports: import warnings
  import numpy
  import pickle
  from io import BytesIO
  from numpy.testing import assert_array_equal, assert_array_almost_equal, assert_almost_equal, assert_equal, assert_
  from dipy.reconst.odf import OdfFit, OdfModel, gfa
  from dipy.direction.peaks import peaks_from_model, peak_directions, peak_directions_nl, reshape_peaks_for_visualization
  from dipy.core.subdivide_octahedron import create_unit_hemisphere
  from dipy.core.sphere import unit_icosahedron
  from dipy.sims.voxel import multi_tensor, multi_tensor_odf
  from dipy.data import get_fnames, get_sphere, default_sphere
  from dipy.core.gradients import gradient_table, GradientTable
  from dipy.core.sphere_stats import angular_similarity
  from dipy.core.sphere import HemiSphere
  from dipy.io.gradients import read_bvals_bvecs
  from dipy.reconst.shm import descoteaux07_legacy_msg, tournier07_legacy_msg
  from dipy.testing.decorators import set_random_number_generator
label_desc: Use image node_id 5 for calling a global function with example usage: test_peak_directions_thorough() without return types