|
1 | 1 | function allen_ccf_npx(tv,av,st) |
2 | 2 | % allen_ccf_npx(tv,av,st) |
| 3 | +% Andy Peters (peters.andrew.j@gmail.com) |
3 | 4 | % |
4 | 5 | % GUI for planning Neuropixels trajectories with the Allen CCF |
5 | 6 | % Part of repository: https://github.com/cortex-lab/allenCCF |
6 | 7 | % - directions for installing atlas in repository readme |
7 | 8 | % - some dependent functions from that repository |
8 | 9 | % |
9 | | -% (optional inputs - if CCF path written in Line 23, loaded automatically) |
| 10 | +% (optional inputs - if CCF path written in Line 22, loaded automatically) |
10 | 11 | % tv, av, st = CCF template volume, annotated volume, structure tree |
11 | 12 |
|
12 | 13 | % Initialize gui_data structure |
@@ -127,30 +128,8 @@ function allen_ccf_npx(tv,av,st) |
127 | 128 | update_slice(probe_atlas_gui); |
128 | 129 | update_probe_coordinates(probe_atlas_gui); |
129 | 130 |
|
130 | | -% Print controls |
131 | | -CreateStruct.Interpreter = 'tex'; |
132 | | -CreateStruct.WindowStyle = 'non-modal'; |
133 | | -msgbox( ... |
134 | | - {'\fontsize{12}' ... |
135 | | - '\bf Probe: \rm' ... |
136 | | - 'Arrow keys : translate probe' ... |
137 | | - 'Alt up/down : raise/lower probe' ... |
138 | | - 'Shift arrow keys : rotate probe' ... |
139 | | - 'm : set probe location manually', ... |
140 | | - '\bf 3D brain areas: \rm' ... |
141 | | - ' + : add (list selector)' ... |
142 | | - ' Shift + : add (hierarchy selector)' ... |
143 | | - ' - : remove', ... |
144 | | - '\bf Visibility: \rm' ... |
145 | | - 's : atlas slice (toggle tv/av/off)' ... |
146 | | - 'b : brain outline' ... |
147 | | - 'p : probe' ... |
148 | | - 'a : 3D brain areas' ... |
149 | | - '\bf Other: \rm' ... |
150 | | - 'r : toggle clickable rotation' ... |
151 | | - 'x : export probe coordinates to workspace' ... |
152 | | - 'h : load and plot SHARP-Track histology'}, ... |
153 | | - 'Controls',CreateStruct); |
| 131 | +% Display controls |
| 132 | +display_controls; |
154 | 133 |
|
155 | 134 | end |
156 | 135 |
|
@@ -241,6 +220,10 @@ function key_press(probe_atlas_gui,eventdata) |
241 | 220 | update_probe_angle(probe_atlas_gui); |
242 | 221 | end |
243 | 222 |
|
| 223 | + case 'c' |
| 224 | + % Bring up controls again |
| 225 | + display_controls; |
| 226 | + |
244 | 227 | case 'b' |
245 | 228 | % Toggle brain outline visibility |
246 | 229 | current_visibility = gui_data.handles.cortex_outline.Visible; |
@@ -328,7 +311,7 @@ function key_press(probe_atlas_gui,eventdata) |
328 | 311 |
|
329 | 312 | gui_data.structure_plot_idx(end+1) = curr_plot_structure; |
330 | 313 |
|
331 | | - plot_structure_color = hex2dec(reshape(gui_data.st.color_hex_triplet{curr_plot_structure},3,[]))./255; |
| 314 | + plot_structure_color = hex2dec(reshape(gui_data.st.color_hex_triplet{curr_plot_structure},2,[])')./255; |
332 | 315 | structure_3d = isosurface(permute(gui_data.av(1:slice_spacing:end, ... |
333 | 316 | 1:slice_spacing:end,1:slice_spacing:end) == curr_plot_structure,[3,1,2]),0); |
334 | 317 |
|
@@ -385,7 +368,7 @@ function key_press(probe_atlas_gui,eventdata) |
385 | 368 |
|
386 | 369 | case 'h' |
387 | 370 | % Load probe histology points, plot line of best fit |
388 | | - probe_histology |
| 371 | + probe_histology(probe_atlas_gui); |
389 | 372 | end |
390 | 373 |
|
391 | 374 | % Upload gui_data |
@@ -630,13 +613,13 @@ function update_probe_coordinates(probe_atlas_gui,varargin) |
630 | 613 | % Get brain labels across the probe and trajectory, and intersection with brain |
631 | 614 | pixel_space = 5; |
632 | 615 | trajectory_areas = interp3(single(gui_data.av(1:pixel_space:end,1:pixel_space:end,1:pixel_space:end)), ... |
633 | | - round(trajectory_zcoords/pixel_space),round(trajectory_xcoords/pixel_space),round(trajectory_ycoords/pixel_space)); |
| 616 | + round(trajectory_zcoords/pixel_space),round(trajectory_xcoords/pixel_space),round(trajectory_ycoords/pixel_space),'nearest'); |
634 | 617 | trajectory_brain_idx = find(trajectory_areas > 1,1); |
635 | 618 | trajectory_brain_intersect = ... |
636 | 619 | [trajectory_xcoords(trajectory_brain_idx),trajectory_ycoords(trajectory_brain_idx),trajectory_zcoords(trajectory_brain_idx)]'; |
637 | 620 |
|
638 | 621 | probe_areas = interp3(single(gui_data.av(1:pixel_space:end,1:pixel_space:end,1:pixel_space:end)), ... |
639 | | - round(probe_zcoords/pixel_space),round(probe_xcoords/pixel_space),round(probe_ycoords/pixel_space))'; |
| 622 | + round(probe_zcoords/pixel_space),round(probe_xcoords/pixel_space),round(probe_ycoords/pixel_space),'nearest')'; |
640 | 623 | probe_area_boundaries = intersect(unique([find(~isnan(probe_areas),1,'first'); ... |
641 | 624 | find(diff(probe_areas) ~= 0);find(~isnan(probe_areas),1,'last')]),find(~isnan(probe_areas))); |
642 | 625 | probe_area_centers = probe_area_boundaries(1:end-1) + diff(probe_area_boundaries)/2; |
@@ -669,28 +652,96 @@ function update_probe_coordinates(probe_atlas_gui,varargin) |
669 | 652 | end |
670 | 653 |
|
671 | 654 |
|
672 | | -function probe_histology |
673 | | -% Load histology points from P Shamash's program and draw best-fit line |
| 655 | +function probe_histology(probe_atlas_gui) |
| 656 | +% Load histology points |
| 657 | +% UNDER CONSTRUCTION |
| 658 | +% (used to use SHARP-Track, now using mine) |
| 659 | + |
| 660 | +% Get guidata |
| 661 | +gui_data = guidata(probe_atlas_gui); |
674 | 662 |
|
675 | | -% (AP_cortexlab_filename option: 'probe_histology') |
676 | 663 | [probe_file,probe_path] = uigetfile('*.mat','Choose probe coordinate file'); |
677 | 664 | load([probe_path,probe_file]); |
678 | 665 |
|
679 | | -histology_points = pointList.pointList{1}; |
| 666 | +if exist('pointList','var') |
| 667 | + histology_points = pointList.pointList{1}; |
| 668 | +elseif exist('probe_ccf','var') |
| 669 | + histology_points = probe_ccf(1).points; % only use first probe |
| 670 | +end |
680 | 671 |
|
681 | 672 | r0 = mean(histology_points,1); |
682 | 673 | xyz = bsxfun(@minus,histology_points,r0); |
683 | 674 | [~,~,V] = svd(xyz,0); |
684 | 675 | histology_probe_direction = V(:,1); |
685 | 676 |
|
686 | | -t = [-1000,1000]; |
687 | | -P = bsxfun(@plus,bsxfun(@times,t',histology_probe_direction'),r0); |
688 | | -plot3(histology_points(:,3),histology_points(:,1),histology_points(:,2),'.b','MarkerSize',20); |
689 | | -line(P(:,3),P(:,1),P(:,2),'color','k','linewidth',2) |
| 677 | +probe_eval_points = [-1000,1000]; |
| 678 | +probe_line_endpoints = bsxfun(@plus,bsxfun(@times,probe_eval_points',histology_probe_direction'),r0); |
| 679 | + |
| 680 | +% Philip's GUI: not saved in native CCF order? |
| 681 | +% plot3(histology_points(:,3),histology_points(:,1),histology_points(:,2),'.b','MarkerSize',20); |
| 682 | +% line(P(:,3),P(:,1),P(:,2),'color','k','linewidth',2) |
| 683 | + |
| 684 | +% % Mine: saved in native CCF order [AP,DV,ML] |
| 685 | +plot3(histology_points(:,1),histology_points(:,3),histology_points(:,2),'.b','MarkerSize',20); |
| 686 | +line(probe_line_endpoints(:,1),probe_line_endpoints(:,3),probe_line_endpoints(:,2),'color','k','linewidth',2) |
| 687 | + |
| 688 | +% Place the probe on the histology best-fit axis |
| 689 | +[ap_max,dv_max,ml_max] = size(gui_data.tv); |
| 690 | + |
| 691 | +probe_ref_top = probe_line_endpoints(1,[1,3,2]); |
| 692 | +probe_ref_bottom = probe_line_endpoints(2,[1,3,2]); |
| 693 | +probe_ref_vector = [probe_ref_top;probe_ref_bottom]'; |
| 694 | + |
| 695 | +set(gui_data.handles.probe_ref_line,'XData',probe_ref_vector(1,:), ... |
| 696 | + 'YData',probe_ref_vector(2,:), ... |
| 697 | + 'ZData',probe_ref_vector(3,:)); |
| 698 | + |
| 699 | +probe_vector = [probe_ref_vector(:,1),diff(probe_ref_vector,[],2)./ ... |
| 700 | + norm(diff(probe_ref_vector,[],2))*gui_data.probe_length + probe_ref_vector(:,1)]; |
| 701 | +set(gui_data.handles.probe_line,'XData',probe_vector(1,:), ... |
| 702 | + 'YData',probe_vector(2,:),'ZData',probe_vector(3,:)); |
| 703 | + |
| 704 | +% Upload gui_data |
| 705 | +[theta,phi] = cart2sph(diff(probe_ref_vector(1,:)),diff(probe_ref_vector(2,:)),diff(probe_ref_vector(3,:))); |
| 706 | +gui_data.probe_angle = ([theta,phi]/(2*pi))*360; |
| 707 | +guidata(probe_atlas_gui, gui_data); |
| 708 | + |
| 709 | +% Update the slice and probe coordinates |
| 710 | +update_slice(probe_atlas_gui); |
| 711 | +update_probe_coordinates(probe_atlas_gui); |
| 712 | + |
690 | 713 |
|
691 | 714 | end |
692 | 715 |
|
| 716 | +function display_controls |
693 | 717 |
|
| 718 | +% Print controls |
| 719 | +CreateStruct.Interpreter = 'tex'; |
| 720 | +CreateStruct.WindowStyle = 'non-modal'; |
| 721 | +msgbox( ... |
| 722 | + {'\fontsize{12}' ... |
| 723 | + '\bf Probe: \rm' ... |
| 724 | + 'Arrow keys : translate probe' ... |
| 725 | + 'Alt/Option up/down : raise/lower probe' ... |
| 726 | + 'Shift arrow keys : rotate probe (around top)' ... |
| 727 | + 'm : set probe location manually', ... |
| 728 | + '\bf 3D brain areas: \rm' ... |
| 729 | + ' =/+ : add (list selector)' ... |
| 730 | + ' Shift =/+ : add (hierarchy selector)' ... |
| 731 | + ' - : remove', ... |
| 732 | + '\bf Visibility: \rm' ... |
| 733 | + 's : atlas slice (toggle tv/av/off)' ... |
| 734 | + 'b : brain outline' ... |
| 735 | + 'p : probe' ... |
| 736 | + 'a : 3D brain areas' ... |
| 737 | + '\bf Other: \rm' ... |
| 738 | + 'r : toggle clickable rotation' ... |
| 739 | + 'x : export probe coordinates to workspace' ... |
| 740 | + 'h : load and plot histology-defined trajectory', ... |
| 741 | + 'c : bring up controls box'}, ... |
| 742 | + 'Controls',CreateStruct); |
| 743 | + |
| 744 | +end |
694 | 745 |
|
695 | 746 |
|
696 | 747 |
|
|
0 commit comments