Code covered by the BSD License  

Highlights from
Application Deployment with MATLAB (July 2007)

image thumbnail
from Application Deployment with MATLAB (July 2007) by David Forstot
Presentation and demos from the Webinar "Application Deployment with MATLAB" (July 26th 2007)

quakeGUI(varargin)
function varargout = quakeGUI(varargin)
% QUAKEGUI M-file for quakeGUI.fig
%      QUAKEGUI, by itself, creates a new QUAKEGUI or raises the existing
%      singleton*.
%
%      H = QUAKEGUI returns the handle to a new QUAKEGUI or the handle to
%      the existing singleton*.
%
%      QUAKEGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in QUAKEGUI.M with the given input arguments.
%
%      QUAKEGUI('Property','Value',...) creates a new QUAKEGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before quakeGUI_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to quakeGUI_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help quakeGUI

% Last Modified by GUIDE v2.5 12-Jul-2007 15:18:58

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @quakeGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @quakeGUI_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before quakeGUI is made visible.
function quakeGUI_OpeningFcn(hObject, eventdata, handles, varargin) %#ok
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to quakeGUI (see VARARGIN)

% Choose default command line output for quakeGUI
handles.output = hObject;

load icons
if ~isfield(handles, 'tb')
  handles.tb = uitoolbar(hObject);
  handles.LoadFileBtn = uipushtool(handles.tb, 'ClickedCallback', @localLoadClickFcn, ...
    'CData', openDocCData, ...
    'TooltipString', 'Load File...');
  handles.ZoomBtn = uitoggletool(handles.tb, 'ClickedCallback', @localZoomClickFcn, ...
    'CData', zoomCData, ...
    'TooltipString', 'Zoom');
  handles.Rotate3DBtn = uitoggletool(handles.tb, 'ClickedCallback', @localRotateClickFcn, ...
    'CData', rotate3dCData, ...
    'TooltipString', 'Rotate');
  handles.HelpBtn = uipushtool(handles.tb, 'ClickedCallback', @localHelpClickFcn, ...
    'CData', helpCData, ...
    'TooltipString', 'Help', ...
    'Separator', 'on');
end

handles.AccelLineHandles = zeros(1, 9);
handles.AccelLineHandles(1:3) = plot(NaN, NaN, 'g', NaN, NaN, 'b', NaN, NaN, 'r--', ...
  'Parent', handles.EastWestAccelAxes);
handles.AccelLineHandles(4:6) = plot(NaN, NaN, 'g', NaN, NaN, 'b', NaN, NaN, 'r--', ...
  'Parent', handles.NorthSouthAccelAxes);
handles.AccelLineHandles(7:9) = plot(NaN, NaN, 'g', NaN, NaN, 'b', NaN, NaN, 'r--', ...
  'Parent', handles.VerticalAccelAxes);
%set(handles.AccelLineHandles([1 4 7]), 'Color', [0 1 0]);
set(handles.AccelLineHandles([1 2 4 5 7 8]), 'LineWidth', 1.5);
set(handles.AccelLineHandles([3 6 9]), 'LineWidth', 2);
set(handles.AccelLineHandles, 'HitTest', 'off');

set([handles.EastWestAccelAxes, handles.NorthSouthAccelAxes, handles.VerticalAccelAxes], 'ButtonDownFcn', @localAccelLineClickFcn);

handles.FreqLineHandles = zeros(1, 6);
handles.FreqLineHandles(1:2) = plot(NaN, NaN, 'b', NaN, NaN, 'g--', ...
  'Parent', handles.EastWestFreqAxes, 'ButtonDownFcn', @localFreqLineClickFcn);
handles.FreqLineHandles(3:4) = plot(NaN, NaN, 'b', NaN, NaN, 'g--', ...
  'Parent', handles.NorthSouthFreqAxes, 'ButtonDownFcn', @localFreqLineClickFcn);
handles.FreqLineHandles(5:6) = plot(NaN, NaN, 'b', NaN, NaN, 'g--', ...
  'Parent', handles.VerticalFreqAxes, 'ButtonDownFcn', @localFreqLineClickFcn);
set(handles.FreqLineHandles([2 4 6]), 'LineWidth', 2, 'Color', [0 .5 0]);
set(handles.FreqLineHandles([1 3 5]), 'LineWidth', 1.5);
set(handles.FreqLineHandles, 'HitTest', 'off');

set([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'ButtonDownFcn', @localFreqLineClickFcn);

handles.PositionLineHandles = plot3(NaN, NaN, NaN, 'b', NaN, NaN, NaN, 'r.', ...
  'Parent', handles.Position3DAxes, 'LineWidth', 2, 'MarkerSize', 30);
grid on;

hZoom = zoom(hObject);
hRot = rotate3d(hObject);
ax = findobj(hObject, 'type', 'axes');
for iAx = 1:length(ax)
  setAllowAxesZoom(hZoom, ax(iAx), true);
  setAllowAxesRotate(hRot, ax(iAx), false);
end
setAllowAxesZoom(hZoom, handles.Position3DAxes, false);
setAllowAxesRotate(hRot, handles.Position3DAxes, true);


set(handles.Position3DAxes, ...
  'View', [-37.5 30], ...
  'Box', 'on');
xlabel('EastWest');
ylabel('NorthSouth');
zlabel('Vertical');

ylabel(handles.EastWestAccelAxes  , 'EW');
ylabel(handles.EastWestFreqAxes   , 'EW');
ylabel(handles.NorthSouthAccelAxes, 'NS');
ylabel(handles.NorthSouthFreqAxes , 'NS');
ylabel(handles.VerticalAccelAxes  , 'V');
ylabel(handles.VerticalFreqAxes   , 'V');
xlabel(handles.VerticalAccelAxes  , 'time (sec)');
xlabel(handles.VerticalFreqAxes   , 'freq (Hz)');

set([handles.EastWestAccelAxes, ...
  handles.NorthSouthAccelAxes, ...
  handles.EastWestFreqAxes, ...
  handles.NorthSouthFreqAxes], 'xticklabel', '');

handles.detrend_first = false;

% Update handles structure
guidata(hObject, handles);

movegui('center');

if length(varargin) == 2
  localLoadClickFcn(handles.LoadFileBtn, [], varargin{2});
end

% UIWAIT makes quakeGUI wait for user response (see UIRESUME)
% uiwait(handles.QuakeGUIFig);


% --- Outputs from this function are returned to the command line.
function varargout = quakeGUI_OutputFcn(hObject, eventdata, handles) %#ok
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


function CutoffFreqValue_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to CutoffFreqValue (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of CutoffFreqValue as text
%        str2double(get(hObject,'String')) returns contents of CutoffFreqValue as a double

if isfield(handles, 'data')
  localApplyFilter(handles);
end

% --- Executes during object creation, after setting all properties.
function CutoffFreqValue_CreateFcn(hObject, eventdata, handles) %#ok
% hObject    handle to CutoffFreqValue (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in ButterworthOrder.
function ButterworthOrder_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ButterworthOrder (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns ButterworthOrder contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ButterworthOrder

if isfield(handles, 'data')
  localApplyFilter(handles);
end

% --- Executes during object creation, after setting all properties.
function ButterworthOrder_CreateFcn(hObject, eventdata, handles) %#ok
% hObject    handle to ButterworthOrder (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in ApplyFilterOption.
function ApplyFilterOption_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ApplyFilterOption (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of ApplyFilterOption

if isfield(handles, 'data');
  localApplyFilter(handles);
end

if get(hObject, 'Value') == 0
  set([handles.ButterworthOrder, handles.CutoffFreqValue], 'Enable', 'off');
  set(handles.FreqLineHandles([2 4 6]), 'Visible', 'off');
  set([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'ButtonDownFcn', '');
else
  set([handles.ButterworthOrder, handles.CutoffFreqValue], 'Enable', 'on');
  set(handles.FreqLineHandles([2 4 6]), 'Visible', 'on');
  set([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'ButtonDownFcn', @localFreqLineClickFcn);
end


% --- Executes on button press in ResetViewBtn.
function ResetViewBtn_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ResetViewBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


set(handles.Position3DAxes, 'View', [-37.5 30]);


%--------------------------------------------------------------------------
% This controls the toggle button for Rotate3D
function localRotateClickFcn(hObject, eventdata) %#ok

handles = guidata(hObject);

switch get(hObject, 'State')
  case 'on'
    set(handles.ZoomBtn, 'State', 'off'); zoom off;
    set(handles.Position3DAxes, {'XLimMode', 'YLimMode', 'ZLimMode'}, repmat({'manual'}, 1, 3));
    rotate3d on
  case 'off'
    rotate3d off
end


%--------------------------------------------------------------------------
% This controls the toggle button for Zoom
function localZoomClickFcn(hObject, eventdata) %#ok

handles = guidata(hObject);

switch get(hObject, 'State')
  case 'on'
    set(handles.Rotate3DBtn, 'State', 'off'); rotate3d off;
    zoom xon
  case 'off'
    zoom off
end


%--------------------------------------------------------------------------
% This controls the push button for Help
function localHelpClickFcn(hObject, eventdata) %#ok

helpstr = {'Click and drag on Acceleration plots to select different points.', ...
  'Click and drag on Frequency Content plots to select a cutoff frequency.'};
helpdlg(helpstr, 'Help');


%--------------------------------------------------------------------------
% This controls the checkbox for applying filters
function localApplyFilter(handles)

if get(handles.ApplyFilterOption, 'Value') == 1

  % Get parameters for building a lowpass filter
  orders = get(handles.ButterworthOrder, 'String');
  val    = get(handles.ButterworthOrder, 'Value');

  n      = str2double(orders{val});

  cutoff = str2double(get(handles.CutoffFreqValue, 'String'));

  if isnan(cutoff)
    cutoff = handles.data.Fs/4;
    set(handles.CutoffFreqValue, 'String', num2str(cutoff));
  end

  % Create butterworth lowpass filter
  [B, A] = butter(n, 2*cutoff/handles.data.Fs);

  handles.filter.c = cutoff;
  handles.filter.B = B;
  handles.filter.A = A;

  % Apply filter to data
  if ~handles.detrend_first %detrend after filter
    handles.data.filteredData.EWacc = detrend(filtfilt(B, A, handles.data.rawData.EWacc));
    handles.data.filteredData.NSacc = detrend(filtfilt(B, A, handles.data.rawData.NSacc));
    handles.data.filteredData.Vacc  = detrend(filtfilt(B, A, handles.data.rawData.Vacc));
  else
    handles.data.filteredData.EWacc = filtfilt(B, A, handles.data.rawData.EWacc);
    handles.data.filteredData.NSacc = filtfilt(B, A, handles.data.rawData.NSacc);
    handles.data.filteredData.Vacc  = filtfilt(B, A, handles.data.rawData.Vacc);
  end

else
  if 1 %detrend after filter
    handles.data.filteredData.EWacc = detrend(handles.data.rawData.EWacc);
    handles.data.filteredData.NSacc = detrend(handles.data.rawData.NSacc);
    handles.data.filteredData.Vacc  = detrend(handles.data.rawData.Vacc);
  else
    handles.data.filteredData.EWacc = handles.data.rawData.EWacc;
    handles.data.filteredData.NSacc = handles.data.rawData.NSacc;
    handles.data.filteredData.Vacc  = handles.data.rawData.Vacc;
  end
end

% Calculate velocity by integrating acceleration
VelocityEW = cumsum(handles.data.filteredData.EWacc)*handles.data.delta;
VelocityNS = cumsum(handles.data.filteredData.NSacc)*handles.data.delta;
VelocityV  = cumsum(handles.data.filteredData.Vacc)*handles.data.delta;

% Calculate position by integrating velocity
handles.Position.EW = cumsum(VelocityEW)*handles.data.delta;
handles.Position.NS = cumsum(VelocityNS)*handles.data.delta;
handles.Position.V  = cumsum(VelocityV)*handles.data.delta;

% Call plotting routine
localPlotData(handles);

% Update handles structure
guidata(handles.QuakeGUIFig, handles);


%--------------------------------------------------------------------------
% Plotting routine
function localPlotData(handles)

% Update acceleration plots
set(handles.AccelLineHandles([1 2 4 5 7 8]), 'xdata', handles.data.time);
set(handles.AccelLineHandles([1 2 4 5 7 8]), {'ydata'}, ...
  {handles.data.rawData.EWacc; handles.data.filteredData.EWacc; ...
  handles.data.rawData.NSacc; handles.data.filteredData.NSacc; ...
  handles.data.rawData.Vacc; handles.data.filteredData.Vacc});

% Update current point indicator line
set(handles.AccelLineHandles([3 6 9]), 'Visible', 'off');
yl = get([handles.EastWestAccelAxes, handles.NorthSouthAccelAxes, handles.VerticalAccelAxes], 'YLim');
set(handles.AccelLineHandles([3 6 9]), 'xdata', [handles.data.curPt, handles.data.curPt]);
set(handles.AccelLineHandles([3 6 9]), {'ydata'}, yl);
set(handles.AccelLineHandles([3 6 9]), 'Visible', 'on');

% Update frequency content plots
set(handles.FreqLineHandles([1 3 5]), 'xdata', handles.psd.EW.Frequencies);
set(handles.FreqLineHandles([1 3 5]), {'ydata'}, ...
  {handles.psd.EW.Data; handles.psd.NS.Data; handles.psd.V.Data});

% Update cutoff frequency indicator line
set(handles.FreqLineHandles([2 4 6]), 'Visible', 'off');
yl = get([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'YLim');
set(handles.FreqLineHandles([2 4 6]), 'xdata', [handles.filter.c, handles.filter.c]);
set(handles.FreqLineHandles([2 4 6]), {'ydata'}, yl);
set(handles.FreqLineHandles([2 4 6]), 'Visible', 'on');

% Update 3D position plot
set(handles.Position3DAxes, {'XLimMode', 'YLimMode', 'ZLimMode'}, repmat({'auto'}, 1, 3));drawnow;
set(handles.PositionLineHandles(1), {'xdata', 'ydata', 'zdata'}, ...
  {handles.Position.EW, handles.Position.NS, handles.Position.V});drawnow;

% Update current point
id = find(handles.data.time >= handles.data.curPt, 1);
set(handles.PositionLineHandles(2), 'xdata', handles.Position.EW(id), ...
  'ydata', handles.Position.NS(id), ...
  'zdata', handles.Position.V(id));

% Link axes for zooming
linkaxes([handles.EastWestAccelAxes, handles.NorthSouthAccelAxes, handles.VerticalAccelAxes], 'x');
linkaxes([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'x');


%--------------------------------------------------------------------------
% Button down event for specifying cutoff frequency interactively
function localFreqLineClickFcn(hObject, eventdata) %#ok

handles = guidata(hObject);

if isfield(handles, 'data')
  yl = get([handles.EastWestFreqAxes, handles.NorthSouthFreqAxes, handles.VerticalFreqAxes], 'YLim');
  set(handles.FreqLineHandles([2 4 6]), {'ydata'}, yl);

  % Initiate click and drag behavior
  set(handles.QuakeGUIFig, 'WindowButtonMotionFcn', {@localMoveFreqLineFcn, hObject});
  set(handles.QuakeGUIFig, 'WindowButtonUpFcn', {@localFreqLineButtonUpFcn, hObject});

end


%--------------------------------------------------------------------------
% This updates the cutoff frequency line as the mouse moves
function localMoveFreqLineFcn(hObject, eventdata, ax) %#ok

handles = guidata(hObject);
cp = get(ax, 'CurrentPoint');cp = round(cp(1)*10)/10;
c = max([min([cp, handles.data.Fs/2-5]), 1]);
set(handles.CutoffFreqValue, 'String', num2str(c));
set(handles.FreqLineHandles([2 4 6]), 'xdata', [c, c]);


%--------------------------------------------------------------------------
% This terminates the click and drag mode. Apply the filter based on the cutoff
% frequency specified.
function localFreqLineButtonUpFcn(hObject, eventdata, ax)

handles = guidata(hObject);
set(gcbf, 'WindowButtonMotionFcn', '', ...
  'WindowButtonUpFcn', '');

localMoveFreqLineFcn(hObject, eventdata, ax);

localApplyFilter(handles);


%--------------------------------------------------------------------------
% Button down event for specifying current point interactively
function localAccelLineClickFcn(hObject, eventdata) %#ok

handles = guidata(hObject);

if isfield(handles, 'data')
  yl = get([handles.EastWestAccelAxes, handles.NorthSouthAccelAxes, handles.VerticalAccelAxes], 'YLim');
  set(handles.AccelLineHandles([3 6 9]), {'ydata'}, yl);

  % Initiate click and drag behavior
  set(handles.QuakeGUIFig, 'WindowButtonMotionFcn', {@localMoveAccelLineFcn, hObject});
  set(handles.QuakeGUIFig, 'WindowButtonUpFcn', {@localAccelLineButtonUpFcn, hObject});

end


%--------------------------------------------------------------------------
% This updates the current point line as the mouse moves
function handles = localMoveAccelLineFcn(hObject, eventdata, ax) %#ok

handles = guidata(hObject);
cp = get(ax, 'CurrentPoint');
c = max([min([cp(1), max(handles.data.time)]), min(handles.data.time)]);

id = find(handles.data.time >= c, 1);
handles.data.curPt = c;
set(handles.PositionLineHandles(2), 'xdata', handles.Position.EW(id), ...
  'ydata', handles.Position.NS(id), ...
  'zdata', handles.Position.V(id));

set(handles.AccelLineHandles([3 6 9]), 'xdata', [c, c]);


%--------------------------------------------------------------------------
% This terminates the click and drag mode.
function localAccelLineButtonUpFcn(hObject, eventdata, ax)

set(hObject, 'WindowButtonMotionFcn', '', ...
  'WindowButtonUpFcn', '');

handles = localMoveAccelLineFcn(hObject, eventdata, ax);

guidata(hObject, handles);


%--------------------------------------------------------------------------
% This controls the push button for loading data
function localLoadClickFcn(hObject, eventdata, fname) %#ok

handles = guidata(hObject);

if nargin < 3

  [filename, pathname] = uigetfile('*.dat');

  if isnumeric(filename)
    return;
  end

  fname = fullfile(pathname, filename);

end
% Use the function generated from the import wizard
myImportfile(fname);

handles.data.time          = time;
if handles.detrend_first %detrend first
  handles.data.rawData.EWacc = detrend(EWacc);
  handles.data.rawData.NSacc = detrend(NSacc);
  handles.data.rawData.Vacc  = detrend(Vacc);
else
  handles.data.rawData.EWacc = EWacc;
  handles.data.rawData.NSacc = NSacc;
  handles.data.rawData.Vacc  = Vacc;
end
handles.data.Fs            = 1/mean(diff(time));
handles.data.delta         = 1/handles.data.Fs;
handles.data.samples       = length(time);

handles.data.curPt   = 1;

handles.hWelch  = spectrum.welch('Hamming', 2^12, 50);
handles.psd.EW  = psd(handles.hWelch, EWacc, 'Fs', handles.data.Fs);
handles.psd.NS  = psd(handles.hWelch, NSacc, 'Fs', handles.data.Fs);
handles.psd.V   = psd(handles.hWelch, Vacc , 'Fs', handles.data.Fs);

set(handles.MsgText, 'String', '');

localApplyFilter(handles);


%--------------------------------------------------------------------------
% This imports the data file. It was originally auto-generated from the
% Import Wizard
function myImportfile(fileToRead1)
%IMPORTFILE(FILETOREAD1)
%  Imports data from the specified file
%  FILETOREAD1: See also file to read
%  FILETOREAD2: See  FILTER2 and in the: Signal Processing Toolbox, FILTFILT.

%  Auto-generated by MATLAB on 27-Sep-2006 13:36:10

% Import the file
newData1 = importdata(fileToRead1);

% Break the data up into a new structure with one field per column.
colheaders = genvarname(newData1.colheaders);
for i = 1:length(colheaders)
  dataByColumn1.(colheaders{i}) = newData1.data(:, i);
end

% Create new variables in the base workspace from those fields.
vars = fieldnames(dataByColumn1);
for i = 1:length(vars)
  assignin('caller', vars{i}, dataByColumn1.(vars{i}));
end


% --------------------------------------------------------------------
function ExportPositionImage_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ExportPositionImage (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

h = figure;
a2 = copyobj(handles.Position3DAxes, h);
set(a2, 'units', 'normalized', 'position', [.1 .1 .8 .8]);
[fname, pname] = uiputfile('*.png', 'Save as');
if ischar(fname)
  print(h, '-dpng', fullfile(pname,fname));
end
close(h);


% --------------------------------------------------------------------
function ExportGuiImage_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ExportGuiImage (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[fname, pname] = uiputfile('*.png', 'Save as');
if ischar(fname)
  print(handles.QuakeGUIFig, '-dpng', fullfile(pname,fname));
end


% --------------------------------------------------------------------
function ExportMenu_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to ExportMenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



% --------------------------------------------------------------------
function Distance_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to Distance (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

set(handles.MsgText, 'String', 'Click on start of P-Wave', 'Visible', 'on');
[x1,y1] = ginput(1); %#ok<NASGU>
set(handles.MsgText, 'String', 'Click on start of S-Wave');
[x2,y2] = ginput(1); %#ok<NASGU>
distance = (x2-x1)*8;
set(handles.MsgText, 'String', sprintf('Epicenter distance: %0.3f km', distance));


% --- Executes during object creation, after setting all properties.
function QuakeGUIFig_CreateFcn(hObject, eventdata, handles)
% hObject    handle to QuakeGUIFig (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes during object creation, after setting all properties.
function EastWestAccelAxes_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EastWestAccelAxes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate EastWestAccelAxes


% --- Executes on mouse press over axes background.
function EastWestAccelAxes_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to EastWestAccelAxes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function uipanel3_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to uipanel3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


Contact us at files@mathworks.com