-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-visualization_with_fsbrain.R
185 lines (144 loc) · 8.42 KB
/
test-visualization_with_fsbrain.R
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
# This file does contain some examples for visualizing the clusters and their
# overlap with fsbrain. All functions require the 'fsbrain'
# package. This is more a demo than unit tests for brainloc.
test_that("We can show a coordinate and the vertex closest to it.", {
testthat::skip_on_ci();
testthat::skip_on_cran();
if(requireNamespace("fsbrain", quietly = TRUE)) {
fs_info = brainloc:::find.freesurferhome();
if(! fs_info$found) {
testthat::skip("No FreeSurfer installation found on system, but the FreeSurfer fsaverage subject is required for this test.");
}
sjd = file.path(fs_info$found_at, "subjects");
sj = "fsaverage";
options("brainloc.silent" = TRUE);
bp = brainparc_fs(sjd, sj);
query_coords = matrix(c(50,50,50), ncol = 3, byrow = TRUE);
ccv = coord_closest_vertex(query_coords, get_surface(bp)); # find closest vertex.
ccv_coords = get_surface_coords(bp, ccv$both_closest_vertex, ccv$both_hemi); # extract its coords.
# Now display the source coord in red, and the closest vertex in yellow (and draw a red line between them).
fsbrain::vis.subject.annot(sjd, sj, atlas = "aparc", views = "si"); # draw brain
fsbrain::highlight.points.spheres(rbind(query_coords, ccv_coords), color = c("red", "yellow"), radius = 2.0); # draw spheres
fsbrain::vis.paths(list(rbind(query_coords, ccv_coords))); # draw line between spheres.
testthat::expect_equal(1L, 1L); # Avoid skip by testthat.
} else {
testthat::skip("This demo requires the optional dependency fsbrain. Please install it.");
}
})
test_that("We can show a vertex and the distance to surrounding brain regions.", {
testthat::skip_on_ci();
testthat::skip_on_cran();
if(requireNamespace("fsbrain", quietly = TRUE)) {
fs_info = brainloc:::find.freesurferhome();
if(! fs_info$found) {
testthat::skip("No FreeSurfer installation found on system, but the FreeSurfer fsaverage subject is required for this test.");
}
sjd = file.path(fs_info$found_at, "subjects");
sj = "fsaverage";
options("brainloc.silent" = TRUE);
bp = brainparc_fs(sjd, sj);
query_vertex = 16564L;
query_hemi = "lh";
num_regions_to_report = 3L;
res = vertex_closest_regions(bp, vertices=query_vertex, hemis=query_hemi, linkage = "single", distance = "geodesic", num_regions_to_report = num_regions_to_report);
# Now display the query vertex and the centers of the closest regions.
query_vertex_coords = get_surface_coords(bp, query_vertex, query_hemi);
region_closest_coords = as.matrix(res[c("vertex_region_n_point_x","vertex_region_n_point_y","vertex_region_n_point_z")]);
fsbrain::vis.subject.annot(sjd, sj, atlas = "aparc", views = "si", style = "default"); # draw brain
fsbrain::highlight.points.spheres(rbind(query_vertex_coords, region_closest_coords), color = c("red", rep("yellow", num_regions_to_report)), radius = 0.3); # draw spheres
path_coords = matrix(rep(NA, (num_regions_to_report*2*3L)), ncol = 3L);
local_idx = 1L;
for(line_idx in seq.int(1L, num_regions_to_report*2, by=2L)) {
path_coords[line_idx, ] = query_vertex_coords;
path_coords[(line_idx+1L), ] = region_closest_coords[local_idx, ];
local_idx = local_idx + 1L;
}
fsbrain::vis.paths(list(path_coords)); # draw line between spheres.
message(sprintf("Look at brain region '%s' on the '%s' hemisphere (from top).\n", as.character(res$vertex_region_direct[1]), query_hemi));
testthat::expect_equal(1L, 1L); # Avoid skip by testthat.
} else {
testthat::skip("This demo requires the optional dependency fsbrain. Please install it.");
}
})
test_that("We can show the regions of a volume segmentation and their distances.", {
testthat::skip_on_ci();
testthat::skip_on_cran();
if(requireNamespace("fsbrain", quietly = TRUE)) {
if(has_fs()) {
fsh = fs_home();
lutfile = file.path(fsh, "FreeSurferColorLUT.txt");
segfile = file.path(fsh, 'subjects', 'fsaverage', 'mri', 'aseg.mgz');
named_regions = name_regions(segfile, lutfile);
named_regions$Unknown = NULL; # Ignore an atlas region.
sc = segmentation_centers(segfile, named_regions);
regions_dist = dist(sc);
dm = as.matrix(regions_dist); # convert dist object to distance matrix.
testthat::expect_equal(ncol(dm), 43L);
testthat::expect_equal(nrow(dm), 43L);
reg_col = brainloc:::region_color(lutfile, unlist(unname(named_regions)));
sjd = file.path(fsh, "subjects");
fsbrain::vis.subject.annot(sjd, "fsaverage", atlas = "aparc", style = "semitransparent", views = "si");
# Transform point coords from volume to surface space (just different origin):
sc2 = sc;
sc2$cx = sc$cx - 128.0;
sc2$cy = sc$cy - 128.0;
sc2$cz = sc$cz - 128.0;
fsbrain::highlight.points.spheres(sc2, color = reg_col, radius = 2.0);
# Show legend (optional, requires fsbrain > 0.5.2)
#fsbrain::vis.seg.legend(lutfile, segfile);
testthat::expect_equal(1L, 1L); # Avoid skip by testthat.
}
} else {
testthat::skip("This demo requires the optional dependency fsbrain. Please install it.");
}
})
test_that("We can show the connections/adjacencies between the regions of a surface parcellation.", {
testthat::skip_on_ci();
testthat::skip_on_cran();
if(requireNamespace("fsbrain", quietly = TRUE)) {
if(has_fs()) {
fsh = fs_home();
sj = "fsaverage";
sjd = file.path(fsh, 'subjects');
options("brainloc.silent" = TRUE);
bp = brainparc_fs(sjd, sj);
atlas = names(bp$annots); # 'aparc'
centr = brainloc:::region_centroids(bp);
lh_centroids = cbind(centr$lh$x, centr$lh$y, centr$lh$z);
rh_centroids = cbind(centr$rh$x, centr$rh$y, centr$rh$z);
region_neigh = brainparc_neighbors(bp);
# Optional: load the full annots for the region colors.
full_annot = list("lh"=brainloc:::subject.annot(sjd, sj, hemi="lh", atlas = atlas), "rh"=brainloc:::subject.annot(sjd, sj, hemi="rh", atlas = atlas));
#fsbrain::vis.subject.annot(sjd, sj, atlas = atlas, style = "semitransparent", views = "si"); # draw brain
if(requireNamespace("rgl", quietly = TRUE)) { # Force new figure and use white background. The 'rgl' is a hard dependency of fsbrain, and so must exist here, but R CMD CHECK complains if we don't do this.
rgl::open3d();
rgl::bg3d("white");
}
fsbrain::highlight.points.spheres(lh_centroids, color = brainloc:::region_colors(full_annot$lh, centr$lh$region), radius = 1.0); # draw spheres
fsbrain::highlight.points.spheres(rh_centroids, color = brainloc:::region_colors(full_annot$rh, centr$rh$region), radius = 1.0); # draw spheres
for(hemi in c("lh", "rh")) {
neigh = region_neigh[[atlas]][[hemi]];
for(reg1_name in colnames(neigh)) {
for(reg2_name in colnames(neigh)) {
if(nchar(reg1_name) < 1L | nchar(reg2_name) < 1L | reg1_name == "_" | reg2_name == "") { # TODO: investigate and fix empty annot region names.
next;
}
if(reg1_name == reg2_name) {
next;
}
if(neigh[reg1_name, reg2_name] == 1L) {
hemi_centr = centr[[hemi]];
reg1_center = as.vector(hemi_centr[hemi_centr$region==reg1_name, c("x", "y", "z")]);
reg2_center = as.vector(hemi_centr[hemi_centr$region==reg2_name, c("x", "y", "z")]);
coords = list(matrix(c(reg1_center, reg2_center), ncol = 3, byrow = TRUE));
fsbrain::vis.paths(coords, path_color = "#777777");
}
}
}
}
testthat::expect_equal(1L, 1L); # Avoid skip by testthat.
}
} else {
testthat::skip("This demo requires the optional dependency fsbrain. Please install it.");
}
})