% --------------------------------------------------------------------
% Virtual Lab, Experiment #1, Version 1.11
%
% Written by Andrew Dressel with John Antonakakis
% September 1, 2003
% Cornell University
%
% Originally developed with GUIDE in MATLAB 6.5
% but extensively modified to run in MATLAB 5.2
%  - commented out not-yet-implemented setappdata()
%  - moved handles to global structure
%  - shortened very long function names 
%
% Modification History
% version 1.1 - 9/25/2003 - AED & JNA
%    - change disabled edit boxes to enabled text boxes for better visability
%    - updated help dialog to contain a lot more information
%    - added ability to read radius in addition to diameter and convert as necessary
%    - fixed bug in offset angle calculation to use radius, not diamter
%    - switched from num2str() to sprintf('%0.3f') to avoid blanks
%    - added ability to read radians in addition to degrees and convert as necessary
%    - fixed bug in calculation of additional, buffer, points. Back off if too far.
%        i.e. beyond absolute maximum value, beyond end of array
%        also, zero if negative
%    - fixed bug in setting axis with max value < min value
%    - clear 1st axis before plotting to make sure user sees correct data
%    - check for and report no data in a file
% version 1.11 - 10/16/2003 - AED & JNA
%    - changed name to Vplot from VL_1_v11
%        (needed to also change function name and all callbacks)
% --------------------------------------------------------------------

function varargout = Vplot(varargin)
	
    global ghandles;
    global file_name title_name
    global t displacement rotation force torque
    global img cmap
    
    if nargin == 0  % LAUNCH GUI
        
        %clear everything to start fresh
        format long; format compact;
        clc; %clear all; %can't do now that ghandles stored as global
        t = []; displacement = []; rotation = []; force = []; torque = []; 
	
        openfig(mfilename, 'reuse');
        
        % Moves the GUI screen so that it is visable no matter what 
        % the users resolution on screen size is
        %movegui(fig, 'onscreen'); 
	
        % Use system color scheme for figure:
        set(ghandles.figure1, 'Color', get(0, 'defaultUicontrolBackgroundColor'));
	
	
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %%
        %%   Add any necessary initialization code here
		
        % --------------------------------------------------------------------
        % get list of text files in default directory
        % --------------------------------------------------------------------
        file_spec = which('Vplot');        %get location of this file
        [path, name, ext, ver] = fileparts(file_spec); %chop up into parts
        dir_struct = dir([path '\*.txt']); %get all the txt files in same directory
        for i = 1:length(dir_struct)       %for each name
            file_names(i, :) = {dir_struct(i).name};
  	     end
        if not(exist('file_names'))
            file_names(1,:) = {' '};
        end

        set(ghandles.popupmenu_files, 'string', file_names); %put file names into popup menu
		
        set(ghandles.edit_offset_strain, 'string', sprintf('%0.3f', 0.001));
        set(ghandles.edit_linear_range_min_torque, 'string', sprintf('%0.3f', 0));
        set(ghandles.edit_linear_range_max_torque, 'string', sprintf('%0.3f', 0));
		
        %%
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
        if nargout > 0
            varargout{1} = fig;
        end
	
    elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK
	
        try
            if (nargout)
                [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
            else
                feval(varargin{:}); % FEVAL switchyard
            end
        catch
            disp(lasterr);
        end
    end
return

% --------------------------------------------------------------------
% Handle selection from popupmenu of files
% --------------------------------------------------------------------
function varargout = popupmenu_files_Callback(h, eventdata, handles, varargin)

    global ghandles
    global file_name title_name
    global t displacement rotation force torque
    
    % --------------------------------------------------------------------
    % Initialize some variables
    % --------------------------------------------------------------------
    t = []; displacement = []; rotation = []; force = []; torque = []; 
    gauge_length = 0;
    inner_diameter = 0;
    outer_diameter = 0;
    inner_radius = 0;
    outer_radius = 0;
    radial_factor = 1;  %default is radians, no conversion necessary
    % --------------------------------------------------------------------
    % get name of file user selected
    % --------------------------------------------------------------------
    selected = get(h, 'Value');         %get the number of the item user selected
    files = get(h, 'String');           %get list of file names user selected from
    file_name = files{selected, 1};     %get name of file user selected
    % --------------------------------------------------------------------
    % check to see if it is valid
    % --------------------------------------------------------------------
    if length(file_name) == 5 & file_name == 'blank'
        %msg = 'no file specified'      %for debugging
    elseif strcmp(file_name(1), ' ')
        warndlg('No data file specified.', 'Warning');
    else
        fid = fopen(file_name, 'rt');    %open the file for reading as text
        % --------------------------------------------------------------------
        % skip over header information, looking for key words: 'Time Displacement Rotation Force Torque'
        % --------------------------------------------------------------------
        new_line = fgets(fid);          %read a line from the file
        while new_line ~= -1            %as long as there are lines to read
            [a] = sscanf(new_line, '%s'); %extract non-white-space characters
            if length(a) == 35          %if 35 characters extracted
                if a == 'TimeDisplacementRotationForceTorque'
                    break               %get out of while loop
                end
            end
            [a] = sscanf(new_line, '%s'); %extract non-white-space characters
            if length(a) == 12          %if 12 characters extracted
                if a == 'SecmmradNN-m'  %if radians
                    radial_factor = 1;  %no conversion necessary
                elseif a == 'SecmmdegNN-m'
                    radial_factor = pi/180; %convert to radians
                end
            end
             
            [value, count] = sscanf(new_line, 'Outer diameter: %f mm');
            if count ~= 0
                outer_diameter = value;
            end
            [value, count] = sscanf(new_line, 'Inner diameter: %f mm');
            if count ~= 0
                inner_diameter = value;
            end
            [value, count] = sscanf(new_line, 'Outer radius: %f mm');
            if count ~= 0
                outer_radius = value;
            end
            [value, count] = sscanf(new_line, 'Inner radius: %f mm');
            if count ~= 0
                inner_radius = value;
            end
            [value, count] = sscanf(new_line, 'Gauge length: %f mm');
            if count ~= 0
                gauge_length = value;
            end
            new_line = fgets(fid);      %read the next line from the file
        end
        if outer_diameter == 0 & outer_radius ~= 0
           outer_diameter = outer_radius * 2;
        end
        if inner_diameter == 0 & inner_radius ~= 0
           inner_diameter = inner_radius * 2;
        end
        if new_line ~= -1               %if the last (previous) line read is valid
            new_line = fgets(fid);      %skip over line of column units
            % --------------------------------------------------------------------
            % read the date from the file
            % --------------------------------------------------------------------
            i = 0; j = 0;               %start keeping count
            while new_line ~= -1        %as long as there are lines to read
                new_line = fgets(fid);  %read the next line from the file
                if new_line ~= -1       %if the line read is valid
                    j = j + 1;          %increment the line counter
                    [a] = sscanf(new_line, '%f %f %f %f %f'); %extract 5 numbers
                    if length(a) == 5   %if 5 numbers extracted
                        i = i + 1;        %increment the line counter
                        t(i) = a(1);    %put the first into time
                        displacement(i) = a(2); %the second into displacement
                        rotation(i) = a(3); %the third into rotation
                        force(i) = a(4); %the forth into force
                        torque(i) = a(5); %and the fifth into torque
                    end
                end
            end
            %if i ~= j
            %    msgbox(sprintf('%d lines read from file,\nbut only %d valid data points found', j, i));
            %end
            if i ~= 0
            % --------------------------------------------------------------------
            % convert to radians, if necessary
            % --------------------------------------------------------------------
            rotation = rotation * radial_factor;
            % --------------------------------------------------------------------
            % display the data
            % --------------------------------------------------------------------
            axes(ghandles.axes2);        %switch to the proper set of axes (bottom)
            cla;                         %clear whatever was there
            axes(ghandles.axes1);        %switch to the proper set of axes (top)
            cla;                         %clear whatever was there
            plot(rotation, torque, '-');     %display rotation vs torque
            xlabel('Rotation in Radians');
            ylabel('Torque in N-m');
            % --------------------------------------------------------------------
            % find maximums
            % --------------------------------------------------------------------
            max_rotation = max(rotation);
            max_torque = max(torque);
            % --------------------------------------------------------------------
            % display maximums
            % --------------------------------------------------------------------
            set(ghandles.edit_max_rotation, 'string', sprintf('%0.3f', max_rotation));
            set(ghandles.edit_max_torque, 'string', sprintf('%0.3f', max_torque));
            % --------------------------------------------------------------------
            % handle special characters in file name, '_' (underscore),
            % so they display correctly in title
            % --------------------------------------------------------------------
            j = 1;                      %keep track of number of characters in title
            title_name = [];            %clear out whatever might be in there
            for i = 1:length(file_name) %for each character in file name
                if file_name(i) == '_'  %if it is an underscore
                    title_name(j) = '\';%precede it with a slash
                    j = j + 1;          %increment number of characters in title
                end
                title_name(j) = file_name(i); %copy character from file name to title
                j = j + 1;              %increment number of characters in title
            end
            title_name = ['Torque vs Rotation from file: ' title_name];
            title(title_name);          %display title
            % --------------------------------------------------------------------
            % get min and max torque values
            % --------------------------------------------------------------------
            linear_range_min_torque = min(torque);
            linear_range_max_torque = max(torque);
            % --------------------------------------------------------------------
            % set min and max torque values into edit text
            % --------------------------------------------------------------------
            set(ghandles.edit_linear_range_min_torque, 'string', sprintf('%0.3f', linear_range_min_torque));
            set(ghandles.edit_linear_range_max_torque, 'string', sprintf('%0.3f', linear_range_max_torque));
            % --------------------------------------------------------------------
            % set inner & outer diameter and gauge length values
            % --------------------------------------------------------------------
            set(ghandles.edit_gauge_length, 'string', sprintf('%0.3f', gauge_length));
            set(ghandles.edit_inner_diameter, 'string', sprintf('%0.3f', inner_diameter));
            set(ghandles.edit_outer_diameter, 'string', sprintf('%0.3f', outer_diameter));
            else
                msgbox(sprintf('%d lines read from file,\nbut no valid data points found', j));
            end
        else
            warndlg([file_name ' is not a valid data file.'], 'Warning');
        end
        fclose(fid);                    %close the file
    end
return

% --------------------------------------------------------------------
% handle 'Replot' Button
% --------------------------------------------------------------------
function pushbutton_replot_Callback(hObject, eventdata, handles)

    global ghandles;
    global t displacement rotation force torque
    if length(torque) == 0                                       %if no data
        warndlg(['Select a data file first.'], 'Warning');       %warn user
    else
        max_rotation = str2num(get(ghandles.edit_max_rotation, 'string'));%get value user entered
        max_torque = str2num(get(ghandles.edit_max_torque, 'string'));%get value user entered
        axes(ghandles.axes1);                                    %switch to the proper set of axes (bottom)
        a = axis;
        a(2) = max_rotation;
        a(4) = max_torque;
        axis(a);
    end
return

% --------------------------------------------------------------------
% handle 'Plot linear range' button
% --------------------------------------------------------------------
function pushbutton_plt_lin_rng_Callback(hObject, eventdata, handles)

    global ghandles
    global file_name title_name
    global t displacement rotation force torque
    
    if length(torque) == 0                                       %if no data
        warndlg(['Select a data file first.'], 'Warning'); %warn user
    else
        % --------------------------------------------------------------------
        % get gauge_length and outer_diameter from controls where we put it
        % after reading it from the data file
        % --------------------------------------------------------------------
        gauge_length = str2num(get(ghandles.edit_gauge_length, 'string'));
        outer_diameter = str2num(get(ghandles.edit_outer_diameter, 'string'));
        % --------------------------------------------------------------------
        % get offset strain specified by user and calculate and display
        % offset_angle
        % --------------------------------------------------------------------
        offset_strain = str2num(get(ghandles.edit_offset_strain, 'string'));  %get value user entered
        offset_angle = (offset_strain*gauge_length)/(outer_diameter/2);
        set(ghandles.edit_offset_angle, 'string', sprintf('%0.3f', offset_angle));    
        % --------------------------------------------------------------------
        % get min and max torques specified by user
        % --------------------------------------------------------------------
        min_torque = str2num(get(ghandles.edit_linear_range_min_torque, 'string')); %get value user entered
        max_torque = str2num(get(ghandles.edit_linear_range_max_torque, 'string')); %get value user entered
        

        if max_torque <= min_torque
            warndlg(['Max torque must be greater than min torque.'], 'Warning');
        else
            % --------------------------------------------------------------------
            % find min and max torques specified by user in the data
            % note: need to find max first to make sure that min is before max
            % --------------------------------------------------------------------
            max_index = 1;                                       %start at beginning
            max_diff = max_torque;                               %initialize maximum difference
            for i = 1:length(torque)                             %loop through all data points
                if abs(max_torque - torque(i)) < max_diff        %if difference is less
                    max_index = i;                               %keep track of this torque
                    max_diff = abs(max_torque - torque(i));      %calculate new difference
                end
            end
            min_index = 1;                                       %start at beginning
            min_diff = max_torque;                               %initialize maximum difference
            for i = 1:length(torque)                             %loop through all data points
                if abs(min_torque - torque(i)) < min_diff        %if difference is less
                    if i < max_index                             %if we haven't gone past max_torque
                        min_index = i;                           %keep track of this torque
                        min_diff = abs(min_torque - torque(i));  %calculate new difference
                    end
                end
            end
            % --------------------------------------------------------------------
            % calculate offset line
            % --------------------------------------------------------------------
            user_rotation = rotation(min_index:max_index);       %extract section user selected
            user_torque = torque(min_index:max_index);
            [p, s] = polyfit(user_rotation, user_torque, 1);     %calculate straight line fit
            line_rotation = [rotation(min_index) ...             %generate straight line
                             rotation(max_index)];
            line_torque = [(rotation(min_index)*p(1)+p(2)) ...
                           (rotation(max_index)*p(1)+p(2))];
            offset_line_rotation = line_rotation + offset_angle;  %generate straight line with offset
            offset_line_torque = line_torque;
            offset_slope = (offset_line_torque(2) - offset_line_torque(1))/ ...
                           (offset_line_rotation(2) - offset_line_rotation(1));
            offset_intercept = offset_line_torque(1) - offset_line_rotation(1) * offset_slope;
            % --------------------------------------------------------------------
            % calculate index_buffer (number of extra points to plot)
            % --------------------------------------------------------------------
            i = max_index;                                       %start at maximum index
            while i < length(rotation) & (torque(i) > (rotation(i)*offset_slope + offset_intercept))
                i = i + 1;                                       %increment
            end
            index_buffer = round(1.5*(i - max_index));           %use last index
            % --------------------------------------------------------------------
            % back off if beyond absolute max
            % --------------------------------------------------------------------
            [y,i] = max(torque);
            if (max_index + index_buffer) > i                    %if too far
                index_buffer = i - max_index;                    %shorten to maximum
            end
            % --------------------------------------------------------------------
            % back off if beyond end of array (shouldn't happen, but just to be sure)
            % --------------------------------------------------------------------
            if (max_index + index_buffer) > length(torque)       %if too far
                index_buffer = length(torque) - max_index;       %shorten to maximum
            end
            % --------------------------------------------------------------------
            % just zero it if negative
            % --------------------------------------------------------------------
            if index_buffer < 0                                  %if too far
                index_buffer = 0;                                %shorten to maximum
            end
            % --------------------------------------------------------------------
            % lengthen lines to reach extra point
            % --------------------------------------------------------------------
            line_torque(2) = torque(max_index + index_buffer);
            line_rotation(2) = line_rotation(1) + (line_torque(2)-line_torque(1))/offset_slope;
            offset_line_torque(2) = torque(max_index + index_buffer); 
            offset_line_rotation(2) = offset_line_rotation(1) + (offset_line_torque(2)-offset_line_torque(1))/offset_slope;
            % --------------------------------------------------------------------
            % display the subset of data
            % --------------------------------------------------------------------
            axes(ghandles.axes2);                                 %switch to the proper set of axes (bottom)
            cla;                                                 %clear axis (plot area)
            plot(rotation(min_index:(max_index + index_buffer)), ...
                 torque(min_index:(max_index + index_buffer)), 'b', ...
                 line_rotation, line_torque, 'r', ...
                 offset_line_rotation, offset_line_torque, 'g'); 
            xlabel('Rotation in Radians');
            ylabel('Torque in N-m');
            %need to explicitely find min and max because may not be first and last
            min_rotation_axis = min(rotation(min_index:(max_index + index_buffer)));
            max_rotation_axis = max(rotation(min_index:(max_index + index_buffer)));
            min_torque_axis = min(torque(min_index:(max_index + index_buffer)));
            max_torque_axis = max(torque(min_index:(max_index + index_buffer)));
            axis([min_rotation_axis max_rotation_axis min_torque_axis max_torque_axis]);
            a = axis;
            h = text((a(1)+0.05*(a(2)-a(1))),(a(3)+0.9*(a(4)-a(3))), sprintf('y = %1.2fx + %1.2f', p(1), p(2)));
            set(h, 'color', 'r');
            legend('source data', 'linearization', 'linearization + offset',4);
            title('Torque vs Rotation for Linear Range');
        end
    end
return

% --------------------------------------------------------------------
% handle 'Exit' Button
% --------------------------------------------------------------------
function pushbutton_exit_Callback(hObject, eventdata, handles)
    global ghandles
    close(ghandles.figure1);
return

% --------------------------------------------------------------------
% handle 'Save' Menu Item
% --------------------------------------------------------------------
function Save_Callback(hObject, eventdata, handles)

    global file_name
    global img cmap

    if isempty(img)
        warndlg(['Copy an image first with edit>copy'], 'Warning');
    else
        [pathstr,name,ext,version] = fileparts(file_name);       %get just the name, without extension
        [data_file_name, pathname] = uiputfile([name '.bmp'], 'Specify image file name'); %prompt user
        if isequal(data_file_name, 0) | isequal(pathname, 0)     %if they didn't pick or type anything
            disp('User pressed cancel')                         %for debugging
        else
            [pathstr, name, ext, version] = fileparts(data_file_name); %get the extension
            if length(ext) == 0                                  %if none specified
                ext = '.bmp';                                    %use bmp
                data_file_name = [data_file_name ext];           %add extension to file name
            end
            if ext == '.jpg' | ext == '.bmp' | ext == '.png'     %if extension is valid
                imwrite(img, fullfile(pathname,data_file_name)); %write the image to a file
                msgbox(sprintf('wrote %s', fullfile(pathname,data_file_name)));s
            else
                warndlg(['Specify image format (jpg, bmp, or png).'], 'Warning');
            end
        end
	end
return

% --------------------------------------------------------------------
% handle 'Exit' Menu Item
% --------------------------------------------------------------------
function Exit_Callback(hObject, eventdata, handles)
    global ghandles;
    close(ghandles.figure1);
return

% --------------------------------------------------------------------
% handle 'Copy' Menu Item
% --------------------------------------------------------------------
function Copy_Callback(hObject, eventdata, handles)
    global img cmap
    frame = getframe(gcf);
    [img, cmap] = frame2im(frame);
    %[img, cmap] = capture;
    display('image captured');
return

% --------------------------------------------------------------------
% handle 'Help' Menu Item
% --------------------------------------------------------------------
function Help_Callback(hObject, eventdata, handles)
%helpdlg(sprintf('%s\n%s\n\n%s\n\n%s', ...
%                'Select a data file (*.txt) which must be located', ...
%                'in the same directory as this MATLAB program.', ...
%                'Specify a maximum torque for the linear range.', ...
%                'Select ''''Plot Linear Range''''.'), ...
%                'Help');
             
helpdlg(sprintf('%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s', ...
                '1. From the data file drop down menu select the data file you wish to', ...
                '    analyze.', ...
                ' ', ...
                '2. You may change the range of the axis by specifying a maximum torque', ...
                '    and rotation.', ...
                ' ', ...
                '3. The outer and inner diameter, as well as the gage length of the sample', ...
                '    you are analyzing is displayed on the MATLAB GUI.', ...
                ' ', ...
                '4. You may specify the range in which the data is linear by entering a', ...
                '    maximum and minimum torque. For example, if the data seems to be', ...
                '    linear between 2 N-m and 8 N-m then these would be the values you', ...
                '    would use for min and max torque to obtain the linear part of the', ...
                '    graph.', ...
                ' ', ...
                '    The program will plot a few data points beyond the one you specify so', ...
                '    that the yield torque can be easily identified.', ...
                ' ', ...
                '5. In the offset strain input field, you may specify the strain at which', ...
                '    the offset line will start. This number will be used in the following', ...
                '    formula:', ...
                ' ', ...
                '                      Phi = (gamma*L)/r', ...
                ' ', ...
                '    where: -Phi is the offset angle that will be displayed in the offset', ...
                '               angle field', ...
                ' ', ...
                '               -gamma is the offset strain, usually 0.001', ...
                ' ', ...
                '               -L is the gage length of the specimen', ...
                ' ', ...
                '               -r is the outside radius of the specimen', ...
                ' ', ...
                '   The torque at yield can be read from the intersection point of the plot', ...
                '   and offset lines.', ...
                ' ', ...
                '   See slide 9 of Engineered materials chalk talk on the virtual lab', ...
                '   website for further information.'), ...
                'Help');

return

% --------------------------------------------------------------------
% handle 'About' Menu Item
% --------------------------------------------------------------------
function About_Callback(hObject, eventdata, handles)
    helpdlg(sprintf('%s\n%s\n%s\n\n%s\n%s\n%s','Virtual Lab', 'Lab #1', 'Version 1.1', 'by Andrew Dressel with John Antonakakis', 'Cornell University', 'September 2003'), 'About');
return

% --------------------------------------------------------------------
% Create GUI
% --------------------------------------------------------------------
function openfig(filename, policy)

    global ghandles;
    
    % policy - create a new figure or use a singleton. 'new' or 'reuse'.
    persistent hsingleton;
    if strcmpi(policy, 'reuse') & ishandle(hsingleton)
        ghandles.figure1 = hsingleton;
        return;
    end

    ghandles.figure1 = figure(...
    'Units','characters',...
    'Color',[0.925490196078431 0.913725490196078 0.847058823529412],...
    'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],...
    'IntegerHandle','off',...
    'InvertHardcopy',get(0,'defaultfigureInvertHardcopy'),...
    'MenuBar','none',...
    'Name','Virtual Lab (version 1.1)',...
    'NumberTitle','off',...
    'PaperPosition',get(0,'defaultfigurePaperPosition'),...
    'Position',[6 6 160 62],...
    'Renderer',get(0,'defaultfigureRenderer'),...
    'RendererMode','manual',...
    'HandleVisibility','callback',...
    'Tag','figure1',...
    'UserData',zeros(1,0));

    %setappdata(ghandles.figure1, 'GUIDEOptions', struct(...
    %'active_h', [], ...
    %'taginfo', struct(...
    %'figure', 2, ...
    %'popupmenu', 2, ...
    %'pushbutton', 9, ...
    %'edit', 11, ...
    %'text', 24, ...
    %'slider', 3, ...
    %'axes', 3, ...
    %'checkbox', 2, ...
    %'frame', 3), ...
    %'override', 0, ...
    %'resize', 'none', ...
    %'accessibility', 'callback', ...
    %'mfile', 1, ...
    %'callbacks', 1, ...
    %'singleton', 1, ...
    %'blocking', 0, ...
    %'syscolorfig', 1, ...
    %'lastSavedFile', 'D:\MATLAB6p5\work\VL_1.m', ...
    %'release', 12));

    ghandles.frame2 = uicontrol(...
    'Parent',ghandles.figure1,...
    'Units','normalized',...
    'ListboxTop',0,...
    'Position',[0.0274656679151061 0.0799001248439451 0.318352059925094 0.35705368289638],...
    'String',{ '' },...
    'Style','frame',...
    'Tag','frame2');

    ghandles.frame1 = uicontrol(...
    'Parent',ghandles.figure1,...
    'Units','normalized',...
    'ListboxTop',0,...
    'Position',[0.0274656679151061 0.647940074906367 0.317103620474407 0.225967540574282],...
    'String',{ '' },...
    'Style','frame',...
    'Tag','frame1');

    ghandles.popupmenu_files = uicontrol(...
    'Parent',ghandles.figure1,...
    'Units','normalized',...
    'Callback','Vplot(''popupmenu_files_Callback'',gcbo,[],[])',...
    'ListboxTop',0,...
    'Position',[0.123595505617978 0.897627965043695 0.249687890137328 0.0374531835205993],...
    'String','blank',...
    'Style','popupmenu',...
    'Value',1,...
    'Tag','popupmenu_files');

    ghandles.axes1 = axes(...
    'Parent',ghandles.figure1,...
    'CameraPosition',[0.5 0.5 9.16025403784439],...
    'CameraPositionMode',get(0,'defaultaxesCameraPositionMode'),...
    'Color',get(0,'defaultaxesColor'),...
    'ColorOrder',get(0,'defaultaxesColorOrder'),...
    'Position',[0.436953807740325 0.560549313358302 0.499375780274657 0.375780274656679],...
    'XColor',get(0,'defaultaxesXColor'),...
    'YColor',get(0,'defaultaxesYColor'),...
    'ZColor',get(0,'defaultaxesZColor'),...
    'Tag','axes1');

    ghandles.h8 = get(ghandles.axes1,'title');

    set(ghandles.h8,...
    'Parent',ghandles.axes1,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[0.5 1.01846590909091 9.16025403784439],...
    'VerticalAlignment','bottom',...
    'HandleVisibility','off');

    ghandles.h9 = get(ghandles.axes1,'xlabel');

    set(ghandles.h9,...
    'Parent',ghandles.axes1,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[0.497782705099778 -0.0667613636363635 9.16025403784439],...
    'VerticalAlignment','cap',...
    'HandleVisibility','off');

    ghandles.h10 = get(ghandles.axes1,'ylabel');
    
    set(ghandles.h10,...
    'Parent',ghandles.axes1,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[-0.0631929046563193 0.495738636363636 9.16025403784439],...
    'Rotation',90,...
    'VerticalAlignment','baseline',...
    'HandleVisibility','off');

    ghandles.h11 = get(ghandles.axes1,'zlabel');

    set(ghandles.h11,...
    'Parent',ghandles.axes1,...
    'Color',[0 0 0],...
    'HorizontalAlignment','right',...
    'Position',[-0.5509977827051 1.06107954545455 9.16025403784439],...
    'HandleVisibility','off',...
    'Visible','off');

    ghandles.axes2 = axes(...
    'Parent',ghandles.figure1,...
    'CameraPosition',[0.5 0.5 9.16025403784439],...
    'CameraPositionMode',get(0,'defaultaxesCameraPositionMode'),...
    'Color',get(0,'defaultaxesColor'),...
    'ColorOrder',get(0,'defaultaxesColorOrder'),...
    'Position',[0.436953807740325 0.0586766541822722 0.499375780274657 0.377028714107366],...
    'XColor',get(0,'defaultaxesXColor'),...
    'YColor',get(0,'defaultaxesYColor'),...
    'ZColor',get(0,'defaultaxesZColor'),...
    'Tag','axes2');

    ghandles.h13 = get(ghandles.axes2,'title');

    set(ghandles.h13,...
    'Parent',ghandles.axes2,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[0.5 1.01884057971015 9.16025403784439],...
    'VerticalAlignment','bottom',...
    'HandleVisibility','off');

    ghandles.h14 = get(ghandles.axes2,'xlabel');

    set(ghandles.h14,...
    'Parent',ghandles.axes2,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[0.497772828507795 -0.0681159420289852 9.16025403784439],...
    'VerticalAlignment','cap',...
    'HandleVisibility','off');

    ghandles.h15 = get(ghandles.axes2,'ylabel');

    set(ghandles.h15,...
    'Parent',ghandles.axes2,...
    'Color',[0 0 0],...
    'HorizontalAlignment','center',...
    'Position',[-0.0634743875278397 0.497101449275362 9.16025403784439],...
    'Rotation',90,...
    'VerticalAlignment','baseline',...
    'HandleVisibility','off');

    ghandles.h16 = get(ghandles.axes2,'zlabel');

    set(ghandles.h16,...
    'Parent',ghandles.axes2,...
    'Color',[0 0 0],...
    'HorizontalAlignment','right',...
    'Position',[-0.557906458797327 2.21884057971014 9.16025403784439],...
    'HandleVisibility','off',...
    'Visible','off');

    ghandles.edit_linear_range_min_torque = uicontrol(...
    'Parent',ghandles.figure1,...
    'Units','normalized',...
    'BackgroundColor',[1 1 1],...
    'CData',zeros(1,0),...
    'ListboxTop',0,...
    'Position',[0.123595505617978 0.362047440699126 0.124843945068664 0.0324594257178527],...
    'Style','edit',...
    'Tag','edit_linear_range_min_torque',...
    'UserData',zeros(1,0));

    ghandles.edit_linear_range_max_torque = uicontrol(...
    'Parent',ghandles.figure1,...
    'Units','normalized',...
    'BackgroundColor',[1 1 1],...
    'CData',zeros(1,0),...
    'ListboxTop',0,...
    'Position',[0.123595505617978 0.299625468164794 0.124843945068664 0.0324594257178527],...
    'Style','edit',...
    'Tag','edit_linear_range_max_torque',...
    'UserData',zeros(1,0));

ghandles.h17 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0449438202247191 0.272159800249688 0.0736579275905119 0.0561797752808989],...
'String','Max Torque',...
'Style','text',...
'Tag','text3');

ghandles.pushbutton_plot_linear_range = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'Callback','Vplot(''pushbutton_plt_lin_rng_Callback'',gcbo,[],[])',...
'ListboxTop',0,...
'Position',[0.0624219725343321 0.107365792759051 0.249687890137328 0.0362047440699126],...
'String','Plot Linear Range',...
'Tag','pushbutton_plot_linear_range');

ghandles.pushbutton_exit = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'Callback','Vplot(''pushbutton_exit_Callback'',gcbo,[],[])',...
'ListboxTop',0,...
'Position',[0.0624219725343321 0.0274656679151061 0.250333333333333 0.0362047440699126],...
'String','Exit',...
'Tag','pushbutton_exit');

ghandles.edit_offset_strain = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'ListboxTop',0,...
'Position',[0.123595505617978 0.238451935081149 0.124843945068664 0.0324594257178527],...
'String','',...
'Style','edit',...
'Tag','edit_offset_strain');

ghandles.h26 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0474406991260924 0.333333333333333 0.0699126092384519 0.0574282147315855],...
'String','Min Torque',...
'Style','text',...
'Tag','text4');

ghandles.h27 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[-0.00249687890137328 0.880149812734082 0.116104868913858 0.0549313358302122],...
'String','Data file',...
'Style','text',...
'Tag','text5');

ghandles.h28 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'ListboxTop',0,...
'Position',[0.0611735330836454 0.837702871410737 0.249687890137328 0.0262172284644195],...
'String','Specify Graphing Range',...
'Style','text',...
'Tag','text6');

ghandles.h29 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0461922596754057 0.772784019975031 0.0736579275905119 0.0599250936329588],...
'String','Max rotation',...
'Style','text',...
'Tag','text7');

ghandles.edit_max_rotation = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'CData',zeros(1,0),...
'ListboxTop',0,...
'Position',[0.124843945068664 0.803995006242197 0.124843945068664 0.0324594257178527],...
'Style','edit',...
'Tag','edit_max_rotation',...
'UserData',zeros(1,0));

ghandles.h31 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.255930087390762 0.787765293383271 0.0536828963795256 0.0449438202247191],...
'String','(rad)',...
'Style','text',...
'Tag','text8');

ghandles.h32 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0424469413233458 0.711610486891386 0.0711610486891386 0.052434456928839],...
'String','Max Torque',...
'Style','text',...
'Tag','text9');

ghandles.edit_max_torque = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'CData',zeros(1,0),...
'ListboxTop',0,...
'Position',[0.124843945068664 0.735330836454432 0.124843945068664 0.0324594257178527],...
'Style','edit',...
'Tag','edit_max_torque',...
'UserData',zeros(1,0));

ghandles.h34 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.255930087390762 0.715355805243446 0.0599250936329588 0.048689138576779],...
'String','(N m)',...
'Style','text',...
'Tag','text10');

ghandles.h35 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.254681647940075 0.333333333333333 0.0599250936329588 0.0574282147315855],...
'String','(N m)',...
'Style','text',...
'Tag','text11');

ghandles.h36 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.254681647940075 0.277153558052434 0.0636704119850187 0.0511860174781523],...
'String','(N m)',...
'Style','text',...
'Tag','text12');

ghandles.pushbutton_replot = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'Callback','Vplot(''pushbutton_replot_Callback'',gcbo,[],[])',...
'ListboxTop',0,...
'Position',[0.0624219725343321 0.66916354556804 0.249687890137328 0.0362047440699126],...
'String','Replot',...
'Tag','pushbutton_replot');

ghandles.h38 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.00249687890137328 0.561797752808989 0.117353308364544 0.0586766541822722],...
'String','Outer diameter',...
'Style','text',...
'Tag','text13');

ghandles.text_outer_diameter = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'ListboxTop',0,...
'Position',[0.184769038701623 0.466916354556804 0.0649188514357054 0.031210986267166],...
'Style','text',...
'Tag','text_outer_diameter');

ghandles.edit_outer_diameter = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'CData',zeros(1,0),...
'Enable','on',...
'ListboxTop',0,...
'Position',[0.124843945068664 0.593008739076155 0.124843945068664 0.0324594257178527],...
'Style','text',...
'Tag','edit_outer_diameter',...
'UserData',zeros(1,0));

ghandles.h41 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.255930087390762 0.570536828963795 0.0711610486891386 0.0511860174781523],...
'String','(mm)',...
'Style','text',...
'Tag','text15');

ghandles.h42 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.00749063670411985 0.441947565543071 0.113607990012484 0.0549313358302122],...
'String','Gauge length',...
'Style','text',...
'Tag','text16');

ghandles.edit_gauge_length = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'CData',zeros(1,0),...
'Enable','on',...
'ListboxTop',0,...
'Position',[0.126092384519351 0.469413233458177 0.124843945068664 0.0324594257178527],...
'Style','text',...
'Tag','edit_gauge_length',...
'UserData',zeros(1,0));

ghandles.h44 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.257178526841448 0.443196004993758 0.0786516853932584 0.0536828963795256],...
'String','(mm)',...
'Style','text',...
'Tag','text17');

ghandles.h45 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'ListboxTop',0,...
'Position',[0.0599250936329588 0.395755305867665 0.249687890137328 0.0274656679151061],...
'String','Specify Linear Range',...
'Style','text',...
'Tag','text18');

ghandles.edit_offset_angle = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'Enable','on',...
'ListboxTop',0,...
'Position',[0.123595505617978 0.176029962546816 0.124843945068664 0.0324594257178527],...
'String','',...
'Style','text',...
'Tag','edit_offset_angle');

ghandles.h47 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0436953807740325 0.209737827715356 0.0761548064918851 0.0586766541822722],...
'String','Offset strain',...
'Style','text',...
'Tag','text19');

ghandles.h48 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.0449438202247191 0.14856429463171 0.0749063670411985 0.0549313358302122],...
'String','Offset angle',...
'Style','text',...
'Tag','text20');

ghandles.h49 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.254681647940075 0.151061173533084 0.0599250936329588 0.052434456928839],...
'String','(rad)',...
'Style','text',...
'Tag','text21');

ghandles.h50 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','right',...
'ListboxTop',0,...
'Position',[0.00249687890137328 0.49812734082397 0.117353308364544 0.0586766541822722],...
'String','Inner diameter',...
'Style','text',...
'Tag','text22');

ghandles.edit_inner_diameter = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'CData',zeros(1,0),...
'Enable','on',...
'ListboxTop',0,...
'Position',[0.124843945068664 0.530586766541823 0.124843945068664 0.0324594257178527],...
'Style','text',...
'Tag','edit_inner_diameter',...
'UserData',zeros(1,0));

ghandles.h52 = uicontrol(...
'Parent',ghandles.figure1,...
'Units','normalized',...
'HorizontalAlignment','left',...
'ListboxTop',0,...
'Position',[0.255930087390762 0.506866416978777 0.0711610486891386 0.0511860174781523],...
'String','(mm)',...
'Style','text',...
'Tag','text23');

ghandles.FileMenu = uimenu(...
'Parent',ghandles.figure1,...
'Label','File',...
'Tag','FileMenu');

ghandles.Save = uimenu(...
'Parent',ghandles.FileMenu,...
'Callback','Vplot(''Save_Callback'',gcbo,[],[])',...
'Label','Save...',...
'Tag','Save');

ghandles.Exit = uimenu(...
'Parent',ghandles.FileMenu,...
'Callback','Vplot(''Exit_Callback'',gcbo,[],[])',...
'Label','Exit',...
'Separator','on',...
'Tag','Exit');

ghandles.EditMenu = uimenu(...
'Parent',ghandles.figure1,...
'Label','Edit',...
'Tag','EditMenu');

ghandles.Copy = uimenu(...
'Parent',ghandles.EditMenu,...
'Callback','Vplot(''Copy_Callback'',gcbo,[],[])',...
'Label','Copy',...
'Tag','Copy');

ghandles.HelpMenu = uimenu(...
'Parent',ghandles.figure1,...
'Label','Help',...
'Tag','HelpMenu');

ghandles.Help = uimenu(...
'Parent',ghandles.HelpMenu,...
'Callback','Vplot(''Help_Callback'',gcbo,[],[])',...
'Label','Help...',...
'Tag','Help');

ghandles.About = uimenu(...
'Parent',ghandles.HelpMenu,...
'Callback','Vplot(''About_Callback'',gcbo,[],[])',...
'Label','About...',...
'Tag','About');

hsingleton = ghandles.figure1;