-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculations.py
184 lines (138 loc) · 5.12 KB
/
calculations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import numpy as np
from scipy.ndimage import binary_erosion
def calculate_length(streamlines):
"""
Calculate the length of each streamline in the bundle.
Parameters:
streamlines (Streamlines): Streamlines of the tract.
Returns:
lengths (list): Lengths of each streamline.
"""
lengths = [np.sum(np.linalg.norm(np.diff(streamline, axis=0), axis=1)) for streamline in streamlines]
return lengths
def calculate_span(streamlines):
"""
Calculate the span of each streamline in the bundle.
Parameters:
streamlines (Streamlines): Streamlines of the tract.
Returns:
spans (list): Spans of each streamline.
"""
spans = [np.linalg.norm(streamline[0] - streamline[-1]) for streamline in streamlines]
return spans
def calculate_curl(lengths, spans):
"""
Calculate the curl of the bundle.
Parameters:
lengths (list): Lengths of each streamline.
spans (list): Spans of each streamline.
Returns:
curl (float): Curl of the bundle.
"""
avg_length = np.mean(lengths)
avg_span = np.mean(spans)
curl = (avg_length / avg_span) * 2
return curl
def calculate_surface_volume(N, voxel_volume):
"""
Calculate the surface volume of the tractogram.
Parameters:
N (int): Number of non-zero voxels.
voxel_volume (float): Volume of a single voxel.
Returns:
surface_volume (float): Surface volume of the tractogram.
"""
return N * voxel_volume
def calculate_surface_area(voxels_data, voxel_spacing):
"""
Calculate the surface area of the tractogram.
Parameters:
voxels_data (ndarray): Voxel data of the tractogram.
voxel_spacing (tuple): Spacing of the voxels in x, y, and z directions.
Returns:
surface_area (float): Surface area of the tractogram.
"""
voxels_binary = voxels_data > 0
surface_voxels = voxels_binary & ~binary_erosion(voxels_binary)
surface_voxel_count = np.count_nonzero(surface_voxels)
voxel_spacing_sq = np.sqrt(np.dot(voxel_spacing, voxel_spacing))
return surface_voxel_count * voxel_spacing_sq ** 2
def calculate_end_surface_area(surface_voxels, voxel_spacing):
"""
Calculate the surface area of the end points.
Parameters:
surface_voxels (int): Number of surface voxels.
voxel_spacing (tuple): Spacing of the voxels in x, y, and z directions.
Returns:
surface_area (float): Surface area of the end points.
"""
return surface_voxels * (voxel_spacing[0] * voxel_spacing[1])
def calculate_radius(area):
"""
Calculate the radius from the given area.
Parameters:
area (float): Area value.
Returns:
radius (float): Calculated radius.
"""
return np.sqrt(area / np.pi)
def calculate_irregularity(area, radius):
"""
Calculate the irregularity based on the area and radius.
Parameters:
area (float): Area value.
radius (float): Radius value.
Returns:
irregularity (float): Calculated irregularity.
"""
return (np.pi * radius * radius) / area
def calculate_diameter(surface_volume, mean_length):
"""
Calculate the diameter of the tractogram.
Parameters:
surface_volume (float): Surface volume of the tractogram.
mean_length (float): Mean length of the streamlines.
Returns:
diameter (float): Diameter of the tractogram.
"""
return 2 * np.sqrt(surface_volume / (np.pi * mean_length))
def calculate_elongation(mean_length, diameter):
"""
Calculate the elongation of the tractogram.
Parameters:
mean_length (float): Mean length of the streamlines.
diameter (float): Diameter of the tractogram.
Returns:
elongation (float): Elongation of the tractogram.
"""
return mean_length / diameter
def calculate_tract_statistics(lengths, spans, voxel_spacing, N, voxels_data):
"""
Calculate various tract statistics.
Parameters:
lengths (list): Lengths of each streamline.
spans (list): Spans of each streamline.
voxel_spacing (tuple): Spacing of the voxels in x, y, and z directions.
N (int): Number of non-zero voxels.
voxels_data (ndarray): Voxel data of the tractogram.
Returns:
tract_stats (dict): Dictionary containing the computed statistics.
"""
curl = calculate_curl(lengths, spans)
voxel_volume = np.prod(voxel_spacing)
surface_volume = calculate_surface_volume(N, voxel_volume)
surface_area = calculate_surface_area(voxels_data, voxel_spacing)
diameter = calculate_diameter(surface_volume, np.mean(lengths))
elongation = calculate_elongation(np.mean(lengths), diameter)
irregularity = surface_area / (np.pi * diameter * np.mean(lengths))
tract_stats = {
"Mean Length": float(np.mean(lengths)),
"Mean Span": float(np.mean(spans) / 2),
"Curl": float(curl),
"Diameter": float(diameter),
"Elongation": float(elongation),
"Total Volume": float(surface_volume),
"Total Surface Area": float(surface_area),
"Irregularity": float(irregularity),
}
return tract_stats