Skip to content

Commit 156270c

Browse files
authored
Added ObliqueSliceFigure.m to /Browsing Functions
ObliqueSliceFigure.m script creates a visualization of a plane slicing through the brain at an arbitrary orientation and position.
1 parent 80fc935 commit 156270c

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
%% oblique Allen Atlas cross-section script
2+
% Michael Krumin, October 2020
3+
4+
% typically can be found in '..\allenCCF\Browsing Functions\' folder
5+
brainGridData = readNPY('brainGridData.npy');
6+
7+
voxelSize = 0.01; % Allen data has voxel size of 10 microns
8+
bp = double(brainGridData);
9+
bp(sum(bp,2)==0,:) = NaN; % when saved to uint16, NaN's become zeros. There aren't any real vertices at (0,0,0) and it shouldn't look much different if there were
10+
bregma = allenCCFbregma; % [AP, DV, ML]
11+
bregma = bregma([1, 3, 2]);
12+
bp = bsxfun(@minus, bp, bregma) * -1 * voxelSize;
13+
14+
% typically can be found in '..\allenCCF\' folder
15+
tv = readNPY('template_volume_10um.npy'); % grey-scale "background signal intensity"
16+
av = readNPY('annotation_volume_10um_by_index.npy'); % the number at each pixel labels the area, see note below
17+
st = loadStructureTree('structure_tree_safe_2017.csv'); % a table of what all the labels mean
18+
19+
%% Normalizing the coordinates to mm and shifting them to be relative to bregma
20+
21+
% rotation the data to have dimensions in the [AP, ML, DV] order for Matlab plotting
22+
tvPerm = permute(tv, [1, 3, 2]);
23+
avPerm = permute(av, [1, 3, 2]);
24+
25+
26+
[nAP, nML, nDV] = size(tvPerm);
27+
apAxis = (single(1:nAP) - bregma(1)) * -voxelSize;
28+
mlAxis = (single(1:nML) - bregma(2)) * -voxelSize;
29+
dvAxis = (single(1:nDV) - bregma(3)) * -voxelSize;
30+
[ML, AP, DV] = meshgrid(mlAxis, apAxis, dvAxis);
31+
32+
33+
[mlSurf, apSurf] = meshgrid(mlAxis, apAxis);
34+
35+
%% Defining the plane
36+
% where do you want the plane?
37+
use3points = false;
38+
if ~use3points
39+
% one option is to define a normal to the plane and a single point:
40+
normal = [0, 1, 1]; % vector normal to the plane (ML, AP, DV)
41+
intersect = [0, -3, -2]; % a point the plain should go through (ML, AP, DV)
42+
43+
else
44+
% another option would be to define three points the plane should pass through:
45+
point1 = [-2, -3, -2];
46+
point2 = [2, -3, -2];
47+
point3 = [0, -2, -3];
48+
49+
% and then the normal and the single intersect point can be calculated
50+
intersect = (point1 + point2 + point3)/3;
51+
normal = cross(point2 - point1, point3 - point1);
52+
normal = normal/norm(normal);
53+
[~, ind] = max(abs(normal));
54+
if normal(ind)<0
55+
normal = -normal;
56+
end
57+
end
58+
59+
% plane equation:
60+
% ax + by + cz + d = 0
61+
% normal = [a, b, c]; intersect = [x0, y0, z0]
62+
% solution:
63+
% d = -(ax0 + by0 + cz0);
64+
% z = (-d - ax - by)/c
65+
dvSurf = (normal * intersect' - normal(1) * mlSurf - normal(2) * apSurf) / normal(3);
66+
67+
%% Actual plotting is done here
68+
69+
plotExtras = true; % bregma, intersection points, normal
70+
71+
figure;
72+
hSlice = slice(ML, AP, DV, single(avPerm), mlSurf, apSurf, dvSurf, 'nearest');
73+
hSlice.LineStyle = 'none';
74+
75+
ax = gca;
76+
77+
load allen_ccf_colormap_2017.mat
78+
colormap(ax, cmap);
79+
caxis(ax, [1 size(cmap,1)]);
80+
81+
hSlice.AlphaData = ones(size(hSlice.XData));
82+
hSlice.AlphaData(hSlice.CData == 1) = 0;
83+
hSlice.AlphaData(isnan(hSlice.CData)) = 0;
84+
hSlice.FaceAlpha = 'flat';
85+
86+
% ax.ZDir = 'reverse';
87+
view(240, 20)
88+
89+
xlabel('ML [mm]');
90+
ylabel('AP [mm]');
91+
zlabel('DV [mm]');
92+
axis equal
93+
94+
% add the mesh of the brain surface
95+
hold on;
96+
plot3(bp(:,2), bp(:, 1), bp(:,3), 'k');
97+
98+
xlim([min(mlAxis), max(mlAxis)]);
99+
ylim([min(apAxis), max(apAxis)]);
100+
zlim([min(dvAxis), max(dvAxis) + 0.5]);
101+
102+
if plotExtras
103+
% plot bregma
104+
plot3(0, 0, 0, 'r.', 'MarkerSize', 30);
105+
% plot the intersect point (or three points defining the plane)
106+
if use3points
107+
plot3(point1(1), point1(2), point1(3), 'b.', 'MarkerSize', 30);
108+
plot3(point2(1), point2(2), point2(3), 'b.', 'MarkerSize', 30);
109+
plot3(point3(1), point3(2), point3(3), 'b.', 'MarkerSize', 30);
110+
else
111+
plot3(intersect(1), intersect(2), intersect(3), 'k.', 'MarkerSize', 30);
112+
end
113+
% plot the normal to the plane
114+
q = quiver3(intersect(1), intersect(2), intersect(3), normal(1), normal(2), normal(3));
115+
q.MaxHeadSize = 10;
116+
q.LineWidth = 3;
117+
q.Color = [0 0 1];
118+
q.AutoScaleFactor = 3 / norm(normal);
119+
end

0 commit comments

Comments
 (0)