1313def afd_map_along_streamlines (sft , fodf , fodf_basis , length_weighting ,
1414 is_legacy = True ):
1515 """
16- Compute the mean Apparent Fiber Density (AFD) and mean Radial fODF
16+ Compute the mean Apparent Fiber Density (AFD) [1] and mean Radial fODF
1717 (radfODF) maps along a bundle.
1818
19+ [1] Raffelt et. al (2012). Apparent fibre density: a novel measure for the
20+ analysis of diffusion-weighted magnetic resonance images.
21+ Neuroimage, 59(4), 3976-3994.
22+
1923 Parameters
2024 ----------
2125 sft : StatefulTractogram
@@ -27,6 +31,8 @@ def afd_map_along_streamlines(sft, fodf, fodf_basis, length_weighting,
2731 Has to be descoteaux07 or tournier07
2832 length_weighting : bool
2933 If set, will weigh the AFD values according to segment lengths
34+ is_legacy : bool
35+ If true, uses legacy basis.
3036
3137 Returns
3238 -------
@@ -37,9 +43,9 @@ def afd_map_along_streamlines(sft, fodf, fodf_basis, length_weighting,
3743 """
3844
3945 afd_sum , rd_sum , weights = \
40- afd_and_rd_sums_along_streamlines (sft , fodf , fodf_basis ,
41- length_weighting ,
42- is_legacy = is_legacy )
46+ _afd_and_rd_sums_along_streamlines (sft , fodf , fodf_basis ,
47+ length_weighting ,
48+ is_legacy = is_legacy )
4349
4450 non_zeros = np .nonzero (afd_sum )
4551 weights_nz = weights [non_zeros ]
@@ -49,8 +55,8 @@ def afd_map_along_streamlines(sft, fodf, fodf_basis, length_weighting,
4955 return afd_sum , rd_sum
5056
5157
52- def afd_and_rd_sums_along_streamlines (sft , fodf , fodf_basis ,
53- length_weighting , is_legacy = True ):
58+ def _afd_and_rd_sums_along_streamlines (sft , fodf , fodf_basis ,
59+ length_weighting , is_legacy = True ):
5460 """
5561 Compute the mean Apparent Fiber Density (AFD) and
5662 mean Radial fODF (radfODF) maps along a bundle.
@@ -67,7 +73,7 @@ def afd_and_rd_sums_along_streamlines(sft, fodf, fodf_basis,
6773 length_weighting : bool
6874 If set, will weigh the AFD values according to segment lengths.
6975 is_legacy : bool, optional
70- Whether or not the SH basis is in its legacy form.
76+ Whether the SH basis is in its legacy form.
7177
7278 Returns
7379 -------
@@ -89,42 +95,46 @@ def afd_and_rd_sums_along_streamlines(sft, fodf, fodf_basis,
8995 _ , n = sph_harm_ind_list (order )
9096 legendre0_at_n = legendre_p_all (order , 0 )[0 ][n ]
9197 sphere_norm = np .linalg .norm (sphere .vertices )
98+ p_matrix = np .eye (fodf_data .shape [3 ]) * legendre0_at_n
9299
100+ # Initializing
93101 afd_sum_map = np .zeros (shape = fodf_data .shape [:- 1 ])
94102 rd_sum_map = np .zeros (shape = fodf_data .shape [:- 1 ])
95103 weight_map = np .zeros (shape = fodf_data .shape [:- 1 ])
96104
97- p_matrix = np .eye (fodf_data .shape [3 ]) * legendre0_at_n
98105 all_split_streamlines = \
99106 subdivide_streamlines_at_voxel_faces (sft .streamlines )
100107 for split_streamlines in all_split_streamlines :
108+ # Get the direction of each segment
101109 segments = split_streamlines [1 :] - split_streamlines [:- 1 ]
102110 seg_lengths = np .linalg .norm (segments , axis = 1 )
103111
104- # Remove points where the segment is zero.
112+ # Remove segments of length zero.
105113 # This removes numpy warnings of division by zero.
106114 non_zero_lengths = np .nonzero (seg_lengths )[0 ]
107115 segments = segments [non_zero_lengths ]
108116 seg_lengths = seg_lengths [non_zero_lengths ]
109117
118+ # Find closest point on sphere
110119 test = np .dot (segments , sphere .vertices .T )
111120 test2 = (test .T / (seg_lengths * sphere_norm )).T
112121 angles = np .arccos (test2 )
113122 sorted_angles = np .argsort (angles , axis = 1 )
114123 closest_vertex_indices = sorted_angles [:, 0 ]
115124
116- # Those starting points are used for the segment vox_idx computations
117- strl_start = split_streamlines [non_zero_lengths ]
118- vox_indices = (strl_start + (0.5 * segments )).astype (int )
125+ # Get the middle voxel of each segment
126+ # (They are already cut per voxel, so the middle voxel is probably the
127+ # same as the start voxel.)
128+ seg_starts = split_streamlines [non_zero_lengths ]
129+ vox_indices = (seg_starts + (0.5 * segments )).astype (int )
119130
120131 normalization_weights = np .ones_like (seg_lengths )
121132 if length_weighting :
122133 normalization_weights = seg_lengths / \
123134 np .linalg .norm (fodf .header .get_zooms ()[:3 ])
124135
125- for vox_idx , closest_vertex_index , norm_weight in zip (vox_indices ,
126- closest_vertex_indices ,
127- normalization_weights ):
136+ for vox_idx , closest_vertex_index , norm_weight in zip (
137+ vox_indices , closest_vertex_indices , normalization_weights ):
128138 vox_idx = tuple (vox_idx )
129139 b_at_idx = b_matrix .T [closest_vertex_index ]
130140 fodf_at_index = fodf_data [vox_idx ]
0 commit comments