📄 eeg_crosshair.m
字号:
function [Xpoint,Ypoint] = eeg_crosshair(action,p,parent);
% EEG_CROSSHAIR - A gui interface for reading (x,y) values from a plot.
%
% A set of mouse driven eeg_crosshairs is placed on the current axes,
% and displays the current (x,y) values of the line plot. There is an
% option to provide data specific values or interpolated values. The
% resolution of the data specific values depends on both the data
% resolution and the GUI interface (mainly mouse movement resolution).
% The interpolated values appear to provide a more continuous function,
% however they too depend on the GUI interface resolution. There are
% no options for extrapolation.
%
% For multiple traces, plots with the same length(xdata) are
% tracked. Each mouse click returns Xpoint,Ypoint values and selecting
% 'done' will remove the GUI and restore the mouse buttons to previous
% values. Selecting 'exit' will remove the GUI and close the figure.
%
% Some further help is given in the tool tips of the GUI.
%
% Useage: x = [1:10]; y(1,:) = sin(x); y(2,:) = cos(x); x2 = x.^2;
% figure; plot(x2,y); eeg_crosshair
%
% $Revision: 1.3 $ $Date: 2003/04/07 06:12:02 $
%
% Licence: GNU GPL, no express or implied warranties
% History: 03/96, Richard G. Cobb <cobbr@plk.af.mil>
% 08/01, Darren.Weber@flinders.edu.au
% replaced obsolete 'table1' with 'interp1'; fixed bug
% with number of 'traces'; rationalized calculations into
% a common subfunction for x,y point calc in 'down','up',
% & 'move' button functions; added option to turn on/off
% interpolation and the exit button; simplified updates
% to graphics using global GUI handle structure.
% 11/01, Darren.Weber@flinders.edu.au
% added tooltips for several GUI handles
% added multiple interpolation methods
% added GUI for data matrix indices (given no interpolation)
% added option to select trace nearest to mouse click point
% reversed order of lines in data matrix to be consistent
% with the value returned from the nearest trace subfunction
% create eeg_crosshair lines after finding all plot lines to
% avoid confusing them with the plot lines
% 01/02, Darren.Weber@flinders.edu.au
% should now work across multiple plot figures, given
% that all gui handles and data are now stored in the
% plot figure 'userdata' handle.
% added functionality to move smoothly from interpolation
% back to the delimited data via the "next/previous"
% buttons.
% 02/02, Darren.Weber@flinders.edu.au
% added functionality to accept general eeg parameter
% structure and call eeg_contours for topo mapping.
% added functions for eeg peak detection and visualization.
% 04/02, Darren.Weber@flinders.edu.au
% only update crosshair if cursor is inside axis limits
% optimised peak updating logic and next/prev peak method
% added option to 'add channels' when using 'view channels'
% added LT/GT for yindex movement
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~exist('action','var')
action = 'init';
elseif isempty(action)
action = 'init';
end
XHR = get(gcbf,'userdata');
action = lower(action);
% Check for specific keys and assign reasonable actions
if strcmp(action, 'keypress'),
CC = get(XHR.gui,'CurrentCharacter');
cc = double(CC);
if cc,
switch cc,
case 27, action = 'done'; % ESC
case 28, action = 'prevx'; % left
case 29, action = 'nextx'; % right
case 30, action = 'ygt'; % up
case 31, action = 'ylt'; % down
case 13, action = 'store'; % return/enter
otherwise, action = 'up'; % all other keys
end
end
end
switch action,
case 'init',
if ~isempty(XHR),
if isfield(XHR,'data'),
fprintf('\nWarning...Crosshair already initialised in current figure.\n');
return;
end
end
% Paint GUI
XHR = INIT;
% Pass input parameters to the figure handles
if exist('p','var'),
XHR.p = p;
%XHR.p = eeg_peaks(XHR.p); % slows init too much
end
if exist('parent','var'), XHR.parent.gui = parent; end
% Update and return values
XHR = updateDATA(XHR);
case 'down', % Mouse Click Down
set(XHR.gui,'WindowButtonMotionFcn','[Xpoint,Ypoint] = eeg_crosshair(''move'');');
set(XHR.gui,'WindowButtonUpFcn','[Xpoint,Ypoint] = eeg_crosshair(''up'');');
XHR = updateDATA(XHR);
case 'move', % Mouse Drag Motion
XHR = updateDATA(XHR);
case 'up', % Mouse Click Up
set(XHR.gui,'WindowButtonMotionFcn',' ');
set(XHR.gui,'WindowButtonUpFcn',' ');
XHR = updateDATA(XHR);
case {'nextx','prevx','changex','nexty','prevy','changey','ylt','ygt'}, % Change X/Y
XHR = moveXY(XHR,action);
case {'nextpeak','prevpeak','nearpeak'}, % Next or Previous Peak
XHR = movepeak(XHR,action);
case {'viewpeaks'}, % View Peaks
XHR = viewpeaks(XHR);
% Store XY values into a history array
case 'store',
Xpoint = get(XHR.handles.xvalue,'Value');
Ypoint = get(XHR.handles.yvalue,'Value');
updateXYhistory(XHR.handles);
case {'done','exit'}, % Exit eeg_crosshairs GUI
handles = fieldnames(XHR.handles);
for i=1:length(handles),
switch handles{i},
case {'axis','datalines','gui'},
otherwise,
h = getfield(XHR.handles,handles{i});
if ishandle(h), delete(h); end
end
end
if strcmp(action,'exit');
close(XHR.gui);
else
set(XHR.gui,'WindowButtonUpFcn','');
set(XHR.gui,'WindowButtonMotionFcn','');
set(XHR.gui,'WindowButtonDownFcn',XHR.handles.button);
set(XHR.gui,'HandleVisibility','on');
set(XHR.gui,'MenuBar','figure');
set(XHR.gui,'userdata',[]);
refresh(XHR.gui);
end
if isfield(XHR,'parent'),
if isfield(XHR.parent,'gui'),
if ishandle(XHR.parent.gui),
% Get the userdata from the parent
parent = get(XHR.parent.gui,'userdata');
if isfield(parent,'p') & isfield(XHR,'p'),
% Update the parent p structure
XHR.p.volt.peaks = [];
parent.p = XHR.p;
set(XHR.parent.gui,'userdata',parent);
if isfield(parent.handles,'EvoltFile'),
set(parent.handles.EvoltFile,'String',parent.p.volt.file);
end
if isfield(parent.handles,'EvoltPath'),
set(parent.handles.EvoltPath,'String',parent.p.volt.path);
end
end
end
end
end
Xpoint = XHR.data.xpoint;
Ypoint = XHR.data.ypoint;
clear XHR;
return;
otherwise,
end
set(XHR.gui,'userdata',XHR);
Xpoint = XHR.data.xpoint;
Ypoint = XHR.data.ypoint;
if ishandle(XHR.gui),
figure(XHR.gui);
end
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function updateXYhistory(H),
Ch = get(H.yindex,'Value');
X = get(H.xvalue,'Value');
Y = get(H.yvalue,'Value');
XY.labels = {'Channel','X','Y'};
XY.data = [Ch,X,Y];
if evalin('base','exist(''XYhist'',''var'');'),
XYhist = evalin('base','XYhist');
if size(XYhist,2) == 3,
XYhist.data(end+1,:) = XY.data;
assignin('base','XYhist',XYhist);
else
fprintf('\nWarning: creating new XYhist in base workspace.\n\n');
assignin('base','XYhist',XY);
end
else
assignin('base','XYhist',XY);
end
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ H ] = updateGUI( H )
InterpMethod = get(H.handles.interp,'Value');
if (InterpMethod > 1)
% There is no specific matrix x-index for
% an interpolated point, but the nearest xindex 'value'
% is always returned from the interp function
% so that next/prev move function works correctly
set(H.handles.xindex,'String','interp');
else
set(H.handles.xindex,'String',num2str(H.data.xindex));
end
set(H.handles.xindex,'Value',H.data.xindex);
% Switch on/off views of traces
if (get(H.handles.traceView,'Value')),
prevY = get(H.handles.yindex,'Value');
currY = uint16(H.data.yindex);
if ~isequal(prevY,currY),
addchan = get(H.handles.traceAdd,'Value');
if ~addchan,
set(H.handles.datalines(prevY),'Visible','off');
end
set(H.handles.datalines(currY),'Visible','on');
else
set(H.handles.datalines(currY),'Visible','on');
end
else
set(H.handles.datalines,'Visible','on');
end
tracestr = sprintf('%d',H.data.yindex);
set(H.handles.yindex,'String',tracestr,'Value',uint16(H.data.yindex));
%set(H.handles.trace,'Value',uint16(H.data.yindex));
% Create the crosshair lines on the figure, crossing at the x,y point
x_rng = get(H.handles.axis,'Xlim');
y_rng = get(H.handles.axis,'Ylim');
set(H.handles.xline,'Xdata',[H.data.xpoint H.data.xpoint],'Ydata',y_rng);
set(H.handles.yline,'Ydata',[H.data.ypoint H.data.ypoint],'Xdata',x_rng);
% Update the x,y values displayed for the x,y point
xstring = sprintf('%14.4f',H.data.xpoint);
ystring = sprintf('%14.4f',H.data.ypoint);
set(H.handles.xvalue,'String',xstring,'Value',H.data.xpoint);
set(H.handles.yvalue,'String',ystring,'Value',H.data.ypoint);
% Update the view of the peak scatterplot
H = viewpeaks(H);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -