|
a |
|
b/code/preprocessing/lib/visual_check.m |
|
|
1 |
function [ good_epochs ] = visual_check( epochs, fs) |
|
|
2 |
%VISUAL_CHECK Summary of this function goes here |
|
|
3 |
% Detailed explanation goes here |
|
|
4 |
|
|
|
5 |
%% Initiations |
|
|
6 |
[epoch_num, epoch_len ]= size(epochs); |
|
|
7 |
time_start = 0; |
|
|
8 |
time_end = epoch_len/fs; |
|
|
9 |
time_axis = linspace(time_start, time_end, epoch_len); |
|
|
10 |
|
|
|
11 |
frequencies = 1:120; |
|
|
12 |
global plot_data; |
|
|
13 |
global my_handles; |
|
|
14 |
|
|
|
15 |
plot_data.epochs = epochs; |
|
|
16 |
plot_data.time_axis = time_axis; |
|
|
17 |
plot_data.epoch_num = epoch_num; |
|
|
18 |
plot_data.bad_epochs_list = []; |
|
|
19 |
plot_data.bad_epoch_num = 0; |
|
|
20 |
plot_data.epoch_index = 1; |
|
|
21 |
plot_data.epoch_info = sprintf('Epoch %d of %d, labeled as %s', plot_data.epoch_index, plot_data.epoch_num, is_epoch_good); |
|
|
22 |
|
|
|
23 |
%% calculate psd for all epochs |
|
|
24 |
[plot_data.PSDs, plot_data.frequency_axis] = pwelch(epochs', [], [], frequencies, fs); |
|
|
25 |
plot_data.PSDs = plot_data.PSDs'; |
|
|
26 |
|
|
|
27 |
%% put ui components |
|
|
28 |
my_handles.main_window = figure; |
|
|
29 |
my_handles.main_window.Color = [1,1,1]; |
|
|
30 |
figure_width = 1000; |
|
|
31 |
figure_height = 600; |
|
|
32 |
my_handles.main_window.InnerPosition=[0,0,figure_width, figure_height]; |
|
|
33 |
|
|
|
34 |
margin_width = 5; |
|
|
35 |
ui_size_width = 50; |
|
|
36 |
ui_size_height = 30; |
|
|
37 |
position = [0,0, ui_size_width,ui_size_height]; |
|
|
38 |
my_handles.left_button = uicontrol('Style', 'pushbutton', 'String', '<-', 'FontSize', 14, 'FontWeight', 'Bold', 'Position', position, 'BackgroundColor', [0.8078, 0.3725, 0.3725],'ForegroundColor', [1,1,1],'Callback', @cbc_left_btn); |
|
|
39 |
|
|
|
40 |
position(1) = position(1) + ui_size_width + margin_width; |
|
|
41 |
my_handles.text_edit = uicontrol('Style', 'edit','String', '1', 'FontSize', 14, 'Position', position); |
|
|
42 |
|
|
|
43 |
position(1) = position(1) + ui_size_width + margin_width; |
|
|
44 |
my_handles.go_button = uicontrol('Style', 'pushbutton','String', 'Go', 'FontSize', 14, 'FontWeight', 'Bold', 'Position', position, 'BackgroundColor', [0.8078, 0.3725, 0.3725],'ForegroundColor', [1,1,1],'Callback', @cbc_go_btn); |
|
|
45 |
|
|
|
46 |
position(1) = position(1) + ui_size_width + margin_width; |
|
|
47 |
my_handles.right_button = uicontrol('Style', 'pushbutton','String', '->', 'FontSize', 14, 'FontWeight', 'Bold', 'Position', position, 'BackgroundColor', [0.8078, 0.3725, 0.3725],'ForegroundColor', [1,1,1],'Callback', @cbc_right_btn); |
|
|
48 |
|
|
|
49 |
position(1) = position(1) + 4*ui_size_height + margin_width; |
|
|
50 |
position(3) = 4*ui_size_width; |
|
|
51 |
my_handles.label_as_bad_button = uicontrol('Style', 'pushbutton','String', 'Label as bad', 'FontSize', 14, 'FontWeight', 'Bold', 'Position', position, 'BackgroundColor', [0.8078, 0.3725, 0.3725],'ForegroundColor', [1,1,1],'Callback', @cbc_label_as_bad_btn); |
|
|
52 |
|
|
|
53 |
position(1) = position(1) + 8*ui_size_height + margin_width; |
|
|
54 |
position(3) = 4*ui_size_width; |
|
|
55 |
my_handles.finish_button = uicontrol('Style', 'pushbutton','String', 'Finish Label', 'FontSize', 14, 'FontWeight', 'Bold', 'Position', position, 'BackgroundColor', [0.8078, 0.3725, 0.3725],'ForegroundColor', [1,1,1],'Callback', @cbc_finish_label_btn); |
|
|
56 |
|
|
|
57 |
|
|
|
58 |
%% refresh plot |
|
|
59 |
refresh_plot(); |
|
|
60 |
|
|
|
61 |
%% wait for return |
|
|
62 |
uiwait(my_handles.main_window); |
|
|
63 |
|
|
|
64 |
%% return updated epochs |
|
|
65 |
good_epochs = epochs; |
|
|
66 |
good_epochs(plot_data.bad_epochs_list,:) = []; |
|
|
67 |
disp('finished'); |
|
|
68 |
end |
|
|
69 |
|
|
|
70 |
|
|
|
71 |
|
|
|
72 |
|
|
|
73 |
%% private functions |
|
|
74 |
%% callbacks |
|
|
75 |
function cbc_left_btn(hObject, event, handles) |
|
|
76 |
global plot_data; |
|
|
77 |
if(plot_data.epoch_index > 1) |
|
|
78 |
plot_data.epoch_index = plot_data.epoch_index - 1; |
|
|
79 |
end |
|
|
80 |
plot_data.epoch_info = sprintf('Epoch %d of %d, labeled as %s', plot_data.epoch_index, plot_data.epoch_num, is_epoch_good); |
|
|
81 |
refresh_plot(); |
|
|
82 |
|
|
|
83 |
end |
|
|
84 |
function cbc_right_btn(hObject, event, handles) |
|
|
85 |
global plot_data; |
|
|
86 |
if(plot_data.epoch_index < plot_data.epoch_num) |
|
|
87 |
plot_data.epoch_index = plot_data.epoch_index + 1; |
|
|
88 |
end |
|
|
89 |
plot_data.epoch_info = sprintf('Epoch %d of %d, labeled as %s', plot_data.epoch_index, plot_data.epoch_num, is_epoch_good); |
|
|
90 |
refresh_plot(); |
|
|
91 |
end |
|
|
92 |
function cbc_go_btn(hObject, event, handles) |
|
|
93 |
global plot_data; |
|
|
94 |
global my_handles; |
|
|
95 |
go_to_index = str2num(my_handles.text_edit.String); |
|
|
96 |
if( go_to_index > plot_data.epoch_num | go_to_index < 1) |
|
|
97 |
go_to_index = 1; |
|
|
98 |
end |
|
|
99 |
plot_data.epoch_index = go_to_index; |
|
|
100 |
plot_data.epoch_info = sprintf('Epoch %d of %d, labeled as %s', plot_data.epoch_index, plot_data.epoch_num, is_epoch_good); |
|
|
101 |
refresh_plot(); |
|
|
102 |
end |
|
|
103 |
function cbc_label_as_bad_btn(hObject, event, handles) |
|
|
104 |
global plot_data; |
|
|
105 |
plot_data.bad_epochs_list = [plot_data.bad_epochs_list plot_data.epoch_index]; |
|
|
106 |
plot_data.bad_epochs_list = unique(plot_data.bad_epochs_list); |
|
|
107 |
plot_data.bad_epoch_num = length(plot_data.bad_epochs_list); |
|
|
108 |
plot_data.epoch_info = sprintf('Epoch %d of %d, labeled as %s', plot_data.epoch_index, plot_data.epoch_num, is_epoch_good); |
|
|
109 |
refresh_plot(); |
|
|
110 |
|
|
|
111 |
disp(['a bad epoch was just labeld: epoch ', num2str(plot_data.epoch_index)]); |
|
|
112 |
end |
|
|
113 |
|
|
|
114 |
function cbc_finish_label_btn(hObject, event, handles) |
|
|
115 |
global my_handles |
|
|
116 |
close(my_handles.main_window); |
|
|
117 |
end |
|
|
118 |
|
|
|
119 |
%% internal functions |
|
|
120 |
function [] = refresh_plot() |
|
|
121 |
%% plot in time field |
|
|
122 |
global plot_data; |
|
|
123 |
global my_handles; |
|
|
124 |
|
|
|
125 |
time_axis = plot_data.time_axis; |
|
|
126 |
epoch = plot_data.epochs(plot_data.epoch_index,:); |
|
|
127 |
subplot(1,2,1); |
|
|
128 |
plot(time_axis, epoch); |
|
|
129 |
xlabel('Time (s)'); |
|
|
130 |
ylabel(['epoch ', num2str(plot_data.epoch_index)]); |
|
|
131 |
title('Epoch in time field'); |
|
|
132 |
my_handles.text_edit.String = num2str(plot_data.epoch_index); |
|
|
133 |
|
|
|
134 |
%% plot PSD |
|
|
135 |
subplot(1,2,2); |
|
|
136 |
frequency_axis = plot_data.frequency_axis; |
|
|
137 |
PSD = plot_data.PSDs(plot_data.epoch_index, :); |
|
|
138 |
area(frequency_axis, PSD, 'EdgeColor', [0.1,0.6,0.1], 'FaceColor', [0.1,0.6,0.1], 'FaceAlpha', 0.4); |
|
|
139 |
xlabel('Frequency (Hz)'); |
|
|
140 |
title('Epoch in frequency field'); |
|
|
141 |
|
|
|
142 |
%sgtitle(plot_data.epoch_info); |
|
|
143 |
end |
|
|
144 |
|
|
|
145 |
function [tag] = is_epoch_good() |
|
|
146 |
global plot_data; |
|
|
147 |
bad_flag = ismember(plot_data.epoch_index, plot_data.bad_epochs_list); |
|
|
148 |
if(bad_flag) |
|
|
149 |
tag = 'bad'; |
|
|
150 |
else |
|
|
151 |
tag = 'good'; |
|
|
152 |
end |
|
|
153 |
|
|
|
154 |
end |