ECG-Kit 1.0
(14,009 bytes)
function [ Label bRefresh bCancel ] = ExpertUserInterface(cCentroid, cCloserExamples, cDistantExamples)
Ventricular_ptr = @(a,b)(ChooseLabel(a,b,'Ventricular'));
Normal_ptr = @(a,b)(ChooseLabel(a,b,'Normal'));
Supraventricular_ptr = @(a,b)(ChooseLabel(a,b,'Supraventricular'));
Unknown_ptr = @(a,b)(ChooseLabel(a,b,'Unknown'));
% open a new figure
fig_hnd = figure();
set(fig_hnd, 'Tag', 'a2hbc' );
screen_size = get(0,'ScreenSize');
set(fig_hnd, 'Name', 'Expert interface' );
set(fig_hnd, 'position', [10 screen_size(4)*0.43 screen_size(3)*0.97 screen_size(4)*0.5] );
%no expert opinion
user_data.Label = [];
user_data.Refresh = false;
user_data.Cancel = false;
%% Plots
CentroidPanel = uipanel( 'Title', [ 'Centroid heartbeat. Total of ' num2str(cCentroid{7}) ' heartbeats in this cluster.' ], ...
'FontSize',12,...
'Position', [0.0011 0.0177 0.3146 0.9693]);
ECG_centroid_hdl = axes('Parent', CentroidPanel);
set(ECG_centroid_hdl, 'units','normalized' );
set(ECG_centroid_hdl, 'position', [0.08 0.48 0.9096 0.4638] )
RR_centroid_hdl = axes('Parent', CentroidPanel);
set(RR_centroid_hdl, 'units','normalized' );
set(RR_centroid_hdl, 'position', [0.08 0.045 0.36 0.35] )
Morph_centroid_hdl = axes('Parent', CentroidPanel);
set(Morph_centroid_hdl, 'units','normalized' );
set(Morph_centroid_hdl, 'position', [0.44 0.045 0.5402 0.35] )
CloserPanel = uipanel( 'Title', [ 'Closer heartbeats. Showing ' num2str(length(cCloserExamples{1})) ' heartbeats.' ], ...
'FontSize',12,...
'Position', [0.3171 0.0177 0.3146 0.9693]);
ECG_closer_hdl = axes('Parent', CloserPanel);
set(ECG_closer_hdl, 'units','normalized' );
set(ECG_closer_hdl, 'position', [0.08 0.48 0.9096 0.4638] )
RR_closer_hdl = axes('Parent', CloserPanel);
set(RR_closer_hdl, 'units','normalized' );
set(RR_closer_hdl, 'position', [0.08 0.045 0.36 0.35] )
Morph_closer_hdl = axes('Parent', CloserPanel);
set(Morph_closer_hdl, 'units','normalized' );
set(Morph_closer_hdl, 'position', [0.44 0.045 0.5402 0.35] )
DistantPanel = uipanel( 'Title',[ 'Distant heartbeats. Showing ' num2str(length(cDistantExamples{1})) ' heartbeats.' ], ...
'FontSize',12,...
'Position', [0.6336 0.0177 0.3146 0.9693]);
ECG_distant_hdl = axes('Parent', DistantPanel);
set(ECG_distant_hdl, 'units','normalized' );
set(ECG_distant_hdl, 'position', [0.08 0.48 0.9096 0.4638] )
RR_distant_hdl = axes('Parent', DistantPanel);
set(RR_distant_hdl, 'units','normalized' );
set(RR_distant_hdl, 'position', [0.08 0.045 0.36 0.35] )
Morph_distant_hdl = axes('Parent', DistantPanel);
set(Morph_distant_hdl, 'units','normalized' );
set(Morph_distant_hdl, 'position', [0.44 0.045 0.5402 0.35] )
%% Buttons
ControlPanel = uipanel( 'Position', [0.9503 0.0177 0.0485 0.9480]);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Ventricular', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[1 0 0], ...
'units','normalized', ...
'position', [ 0.05 0.7119 0.9 0.0500 ], ...
'callback', Ventricular_ptr );
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Supraventricular', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[0 0.5 0], ...
'units','normalized', ...
'position', [ 0.05 0.7843 0.9 0.0500 ], ...
'callback', Supraventricular_ptr);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Normal', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[0 0 1], ...
'units','normalized', ...
'position', [ 0.05 0.8586 0.9 0.0500 ], ...
'callback', Normal_ptr);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Unknown', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[1 1 1], ...
'units','normalized', ...
'position', [ 0.05 0.64 0.9 0.0500 ], ...
'callback', Unknown_ptr);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Skip', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[0 0 1], ...
'units','normalized', ...
'position', [ 0.05 0.5 0.9 0.0500 ], ...
'callback', @SkipCluster);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Refresh', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[0 0 1], ...
'units','normalized', ...
'position', [ 0.05 0.43 0.9 0.0500 ], ...
'callback',@RefreshExamples);
uicontrol('style','pushbutton', ...
'Parent', ControlPanel, ...
'string', 'Cancel', ...
'FontName','Arial', ...
'FontSize',10, ...
'FontWeight','Bold', ...
'ForegroundColor',[1 0 0], ...
'units','normalized', ...
'position', [ 0.05 0.05 0.9 0.0500 ], ...
'callback',@CancelButton);
%% plot data
set(fig_hnd,'ToolBar','figure');
%plot signals
% cCloserExamples = { aux_rel_posQRS ... %relative position of the heartbeat
% aux_ECGslices ... % ecg excerpt
% aux_rel_posRR ... % relative position of the heartbeat
% aux_RRslices ... % RR interval sequence
% };
% cCentroid, cCloserExamples, cDistantExamples
box(ECG_closer_hdl, 'off');
box(RR_closer_hdl, 'off');
box(ECG_distant_hdl, 'off');
box(RR_distant_hdl, 'off');
%% Centroid heartbeat
plot( ECG_centroid_hdl, cCentroid{2} );
hold(ECG_centroid_hdl, 'on');
plot( ECG_centroid_hdl, [ cCentroid{1} cCentroid{1}], [ min(min(cCentroid{2})) max(max(cCentroid{2}))], '--r' );
hold(ECG_centroid_hdl, 'off');
TightAxes(ECG_centroid_hdl);
TimeRes = 0.4;
TimeGrid = fliplr(cCentroid{1}:-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) cCentroid{1}:TimeRes*360:size(cCentroid{2},1)];
set(ECG_centroid_hdl, 'XTick', colvec(TimeGrid));
set(ECG_centroid_hdl, 'XTickLabel', Seconds2HMS((TimeGrid-cCentroid{1})/360) );
title(ECG_centroid_hdl, 'First Two PCA Components' );
box(ECG_centroid_hdl, 'off');
plot( RR_centroid_hdl, cCentroid{4}, '--ob' );
hold(RR_centroid_hdl, 'on');
plot( RR_centroid_hdl, [ cCentroid{3} cCentroid{3}], [ min(min(cCentroid{4})) max(max(cCentroid{4}))], '--r' );
hold(RR_centroid_hdl, 'off');
TightAxes(RR_centroid_hdl);
set(RR_centroid_hdl, 'XTick', cCentroid{3});
set(RR_centroid_hdl, 'XTickLabel', 'Current heartbeat' );
title(RR_centroid_hdl, 'Local RR interval evolution' );
box(RR_centroid_hdl, 'off');
plot( Morph_centroid_hdl, cCentroid{6} );
hold(Morph_centroid_hdl, 'on');
plot( Morph_centroid_hdl, [ cCentroid{5} cCentroid{5}], [ min(min(cCentroid{6})) max(max(cCentroid{6}))], '--r' );
hold(Morph_centroid_hdl, 'off');
TightAxes(Morph_centroid_hdl);
TimeRes = 0.1;
TimeGrid = fliplr(cCentroid{5}:-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) cCentroid{5}:TimeRes*360:size(cCentroid{6},1)];
set(Morph_centroid_hdl, 'XTick', colvec(TimeGrid));
set(Morph_centroid_hdl, 'YTick', []);
set(Morph_centroid_hdl, 'XTickLabel', Seconds2HMS((TimeGrid-cCentroid{5})/360) );
title(Morph_centroid_hdl, 'Morphology details' );
box(Morph_centroid_hdl, 'off');
%% Closer heartbeats
QRS_positions = cCloserExamples{1};
ECG = cCloserExamples{2};
plot( ECG_closer_hdl, (1:size(ECG{1},1))-QRS_positions(1), ECG{1} );
hold(ECG_closer_hdl, 'on');
cellfun(@(a,b)(plot( ECG_closer_hdl, (1:size(a,1))-b, a )), ECG(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
plot( ECG_closer_hdl, [ 0 0 ], [ min(min(cell2mat(ECG))) max(max(cell2mat(ECG)))], '--r' );
hold(ECG_closer_hdl, 'off');
TightAxes(ECG_closer_hdl);
TimeRes = 0.4;
TimeGrid = fliplr(QRS_positions(1):-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) QRS_positions(1):TimeRes*360:size(ECG{1},1)]-QRS_positions(1);
set(ECG_closer_hdl, 'XTick', colvec(TimeGrid));
set(ECG_closer_hdl, 'XTickLabel', Seconds2HMS((TimeGrid)/360) );
title(ECG_closer_hdl, 'First Two PCA Components' );
box(ECG_closer_hdl, 'off');
QRS_positions = cCloserExamples{3};
RR_series = cCloserExamples{4};
plot( RR_closer_hdl, (1:size(RR_series{1},1))-QRS_positions(1), RR_series{1}, ':xb' );
hold(RR_closer_hdl, 'on');
cellfun(@(a,b)(plot( RR_closer_hdl, (1:size(a,1))-b, a, ':xb' )), RR_series(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
plot( RR_closer_hdl, [ 0 0 ], [ min(min(cell2mat(RR_series))) max(max(cell2mat(RR_series)))], '--r' );
hold(RR_closer_hdl, 'off');
TightAxes(RR_closer_hdl);
set(RR_closer_hdl, 'XTick', 0);
set(RR_closer_hdl, 'XTickLabel', 'Current heartbeat' );
title(RR_closer_hdl, 'Local RR interval evolution' );
box(RR_closer_hdl, 'off');
QRS_positions = cCloserExamples{5};
ECG = cCloserExamples{6};
plot( Morph_closer_hdl, (1:size(ECG{1},1))-QRS_positions(1), ECG{1} );
hold(Morph_closer_hdl, 'on');
cellfun(@(a,b)(plot( Morph_closer_hdl, (1:size(a,1))-b, a )), ECG(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
hold(Morph_closer_hdl, 'off');
TightAxes(Morph_closer_hdl);
TimeRes = 0.1;
TimeGrid = fliplr(QRS_positions(1):-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) QRS_positions(1):TimeRes*360:size(ECG{1},1)]-QRS_positions(1);
set(Morph_closer_hdl, 'XTick', colvec(TimeGrid));
set(Morph_closer_hdl, 'XTickLabel', Seconds2HMS((TimeGrid)/360) );
set(Morph_closer_hdl, 'YTick', []);
title(Morph_closer_hdl, 'Morphology details' );
box(Morph_closer_hdl, 'off');
%% Distant heartbeats
QRS_positions = cDistantExamples{1};
ECG = cDistantExamples{2};
plot( ECG_distant_hdl, (1:size(ECG{1},1))-QRS_positions(1), ECG{1} );
hold(ECG_distant_hdl, 'on');
cellfun(@(a,b)(plot( ECG_distant_hdl, (1:size(a,1))-b, a )), ECG(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
plot( ECG_distant_hdl, [ 0 0 ], [ min(min(cell2mat(ECG))) max(max(cell2mat(ECG)))], '--r' );
hold(ECG_distant_hdl, 'off');
TightAxes(ECG_distant_hdl);
TimeRes = 0.4;
TimeGrid = fliplr(QRS_positions(1):-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) QRS_positions(1):TimeRes*360:size(ECG{1},1)]-QRS_positions(1);
set(ECG_distant_hdl, 'XTick', colvec(TimeGrid));
set(ECG_distant_hdl, 'XTickLabel', Seconds2HMS((TimeGrid)/360) );
title(ECG_distant_hdl, 'First Two PCA Components' );
box(ECG_distant_hdl, 'off');
QRS_positions = cDistantExamples{3};
RR_series = cDistantExamples{4};
plot( RR_distant_hdl, (1:size(RR_series{1},1))-QRS_positions(1), RR_series{1}, ':xb' );
hold(RR_distant_hdl, 'on');
cellfun(@(a,b)(plot( RR_distant_hdl, (1:size(a,1))-b, a, ':xb' )), RR_series(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
plot( RR_distant_hdl, [ 0 0 ], [ min(min(cell2mat(RR_series))) max(max(cell2mat(RR_series)))], '--r' );
hold(RR_distant_hdl, 'off');
TightAxes(RR_distant_hdl);
set(RR_distant_hdl, 'XTick', 0);
set(RR_distant_hdl, 'XTickLabel', 'Current heartbeat' );
title(RR_distant_hdl, 'Local RR interval evolution' );
box(RR_distant_hdl, 'off');
QRS_positions = cDistantExamples{5};
ECG = cDistantExamples{6};
plot( Morph_distant_hdl, (1:size(ECG{1},1))-QRS_positions(1), ECG{1} );
hold(Morph_distant_hdl, 'on');
cellfun(@(a,b)(plot( Morph_distant_hdl, (1:size(a,1))-b, a )), ECG(min(end,2):end), num2cell(QRS_positions(min(end,2):end)) );
hold(Morph_distant_hdl, 'off');
TightAxes(Morph_distant_hdl);
TimeRes = 0.1;
TimeGrid = fliplr(QRS_positions(1):-TimeRes*360:1);
TimeGrid = [ TimeGrid(1:end-1) QRS_positions(1):TimeRes*360:size(ECG{1},1)]-QRS_positions(1);
set(Morph_distant_hdl, 'XTick', colvec(TimeGrid));
set(Morph_distant_hdl, 'XTickLabel', Seconds2HMS((TimeGrid)/360) );
set(Morph_distant_hdl, 'YTick', []);
title(Morph_distant_hdl, 'Morphology details' );
box(Morph_distant_hdl, 'off');
%% Wait for user interaction
set(fig_hnd , 'User', user_data );
uiwait(fig_hnd);
if( ishandle(fig_hnd) )
user_data = get(fig_hnd , 'User');
Label = user_data.Label;
bRefresh = user_data.Refresh;
bCancel = user_data.Cancel;
close(fig_hnd);
else
bCancel = true;
Label = [];
bRefresh = [];
end
function ChooseLabel(obj, event_obj, strLabel)
fig_hnd = gcf();
user_data = get(fig_hnd , 'User');
user_data.Label = strLabel;
set(fig_hnd , 'User', user_data );
uiresume(fig_hnd);
function SkipCluster(obj, event_obj)
fig_hnd = gcf();
uiresume(fig_hnd);
function CancelButton(obj, event_obj)
fig_hnd = gcf();
user_data = get(fig_hnd , 'User');
user_data.Cancel = true;
set(fig_hnd , 'User', user_data );
uiresume(fig_hnd);
function RefreshExamples(obj, event_obj)
fig_hnd = gcf();
user_data = get(fig_hnd , 'User');
user_data.Refresh = true;
set(fig_hnd , 'User', user_data );
uiresume(fig_hnd);
function TightAxes(axes_hdl)
axis(axes_hdl, 'tight')
xlimits = xlim(axes_hdl);
xrange = diff(xlimits);
ylimits = ylim(axes_hdl);
yrange = diff(ylimits);
xlim(axes_hdl, xlimits + [ -0.05*xrange 0.05*xrange ] )
ylim(axes_hdl, ylimits + [ -0.05*yrange 0.05*yrange ] )