Code covered by the BSD License  

Highlights from
res_meas

image thumbnail

res_meas

by

 

16 May 2007 (Updated )

GUI for resonator measurement and data download from Signal Analyzers and Oscilloscopes

res_meas(varargin)
function varargout = res_meas(varargin)
%RES_MEAS is a GUI for measuring the resonant frequency of a resonator
% using a Network Analyzer (bode plot or sweep measurement). RES_MEAS can
% also download and save the data from an Analyzer or Oscilloscope.
% RES_MEAS can save the data to a file, and load files for viewing.
%
% If the Instrument Control Toolbox is not installed, the measurement
%  functions will be disabled, but the file Load/Save functions will work.
%
% RES_FEED is an auxiliary script for RES_MEAS which will de-embed a noisy
% resonator measurement. Type "help res_feed" for details.
%
%
%
% requires:
%   kpib.m (v4.5 or higher)
%   measure_res.m (v3.91 or higher)
%   bandqrR.m (v1.5 or higher)
%   ringdownR.m (v1.3 or higher)
%
% M.A. Hopcroft
%      hopcroft at mems dot stanford dot edu
%
% MH Sep2010
% v5.1   Add menu item for Feedthrough Extraction
% v5.04  Bugfixes for deployment (instr ctrl toolbox)

% MH May2010
% v5.03  Bugfixes for ringdown
% v5.02  Made multi-analysis work correctly
% v.500  Add ringdown analysis (multiple analyses based
%          on choice of analyzer)
%        remove front panel display field_bandwidth
%        switch to bandqrR.m
% v4.76  Update default analyzer choice behavior
% v4.74  Include HP_84500 Oscilloscopes
%        minor tweaks to oscilloscope grab
%
% MH NOV2009
% v4.7  Include AG_5071B
%       Small bugfixes for kpib interface, menus
%
% MH FEB2009
% v4.64  added cells, minor bugfixes
%
% MH HKL MAR2008
% v4.62  res.dbfreq by HKL
%        res.dbfreq is frequency corresponds to 3db bandwidth
%        those values are stored in "trace_meas"
%
% MH FEB2008
% v4.61 add support for Hn
%
% MH JAN2008
% v4.60 add support for HP_4195A
%
% MH MAY2007
% v4.59 fix marker bug in grab
% v4.58 add GPIB check to GPIB menu item (function ridentify)
% v4.56 fix ASCII load/save bug (multiple traces)
% v4.54 check for kpib at startup
%       add save Graphic file menu item
% v4.52 fix sweep bug
%       fix Rx Cf calculation bug
%
% MH MAR2007
% v4.5  add "Reset GPIB"
% v4.44 display log Hz properly
% v4.42 add TDS oscilloscope capture (grab)
%       measure buttons are inactive if IC toolbox not installed
% v4.3  help menu, update binary files
% v4.22 display bugfixes
% v4.2  support multiple-measurement files (e.g. TCf_res, mux_TCF)
% v4.1  bugfixes related to single trace display (spectrum)
% v4.01 bugfixes, bias voltage display
%
% MH FEB2007
% v4.0  use "tools" format
%       use measure_res
%       built-in "rconvertdate"
%       use two axes instead of plotyy
%       fix datapath
%       support HP_8560A for Grab only
% v3.82 fixed default Data directory
% v3.81 fixed duplicate "trace_meas" problem
%
%
% MH AUG2006
% v3.8  fixed Sweep for 4395,8753
%       added GPIB check when changing analyzers
%       fixed label for 4395A
%       
% MH JUL2006
% v3.7 added support for HP_8753ES
%
% MH JUN2006
% v3.6 added amp gain as a setting, fix grab function, added plot hold
%
%MH MAR2006
%v3.5
% added time measurement, error check for new fields in showdata
% made bias box a measurement parameter
% modified sweep scale behaviour
% added bias check
% added phase shift
% removed call to bandqr - it is handled by measure_X
% fix showdata fprintf
%
%MH FEB2006
%v3.32
% added bandqr to grab
% get/set behaviour
% improved 4395A sweep function
% added plot of symmetry point on resonator peak
% peak point on/off is immediate
%
%
%MH SEP2005
%v3.2
% added span display
%
%MH SEP2005
%v3.1
% added grab function
% comment out label for 4395
%
%MH MAY2005
%v2.1
%


% RES_MEAS M-file for res_meas.fig
%      RES_MEAS, by itself, creates a new RES_MEAS or raises the existing
%      singleton*.
%
%      H = RES_MEAS returns the handle to a new RES_MEAS or the handle to
%      the existing singleton*.
%
%      RES_MEAS('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RES_MEAS.M with the given input arguments.
%
%      RES_MEAS('Property','Value',...) creates a new RES_MEAS or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before res_meas_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to res_meas_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 res_meas

% Last Modified by GUIDE v2.5 30-Sep-2010 14:33:30

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @res_meas_OpeningFcn, ...
                   'gui_OutputFcn',  @res_meas_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 res_meas is made visible.
function res_meas_OpeningFcn(hObject, eventdata, handles, varargin)
% 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 res_meas (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes res_meas wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = res_meas_OutputFcn(hObject, eventdata, handles)
% 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;
%disp('MATLAB init over')


% ----------------------
%% Startup/Initialize


%%%%%%%%%%
handles.versionstr='res_meas v5.1';
%%%%%%%%%%


% initialize some variables with default values
handles.span2=50e6;
handles.span3=20e6;
handles.avewait=5e6;
handles.use_averaging='off'; % should measurements use averaging or not
  set(handles.menu_averaging,'Checked',handles.use_averaging); % make menu look right
handles.label_points='on'; % highlight the key points on the plot (yes)
  set(handles.menu_label_points,'Checked',handles.label_points);
handles.get_set='on'; % should we get initial settings from the analyzer (yes)
  set(handles.menu_get_set,'Checked',handles.get_set);
handles.updatefiles='off'; % should we update binary files when opened? (yes)
  %set(handles.menu_updatefiles,'Checked',handles.updatefiles); % this menu removed v5
handles.verbose=1; % verbosity level (0,1,2)
handles.datetime=rconvertdate(clock,'file'); % record the time of each measurement
handles.tools.biasset.instr='none';
handles.tools.biasset.gpib=24;
handles.tools.biasset.channel=1;
handles.plothold=0;
handles.amp_gain=0; % gain not specified
% "get new data" checkbox setting - on is default
handles.get_new=1;
maxVal = get(handles.checkbox_newdata,'Max'); 
set(handles.checkbox_newdata,'Value',maxVal);


%handles.paxes = []; % plot axes handles
% set a default files location
if ispc
    if isdir('C:\Data\')
        handles.datapath='C:\Data\';
    else
        handles.datapath=pwd;
    end
else
    if isdir('~/Data/')
        handles.datapath='~/Data/';
    else
        handles.datapath=pwd;
    end
end
% determine if the current location is on the path
%  and disable file location memory if it is not
fp=fileparts(which('res_meas'));
if isempty(strfind(path,fp))
    handles.usedatapath = 0;
else
    handles.usedatapath = 1;
end

% Set default analyzer
% This list is the order of the popup menu, set in the popup menu
%  properties in the gui editor. Update it if you add new instruments to
%  the list.
% 1 = "Select Instrument"
% 2 = 'HP_89410A'
% 3 = 'HP_4395A'
% 4 = 'HP_8753ES'
% 5 = 'HP_4195A'
% 6 = 'AG_E5071B'
% 7 = 'HP_8560A'
% 8 = 'TEK_TDS'
% 9 = 'HP_54600'
% 10 = 'HP_54800'
%
% set the number, gpib addr., and kpib name to change the default
handles.instrument_num=1; 
handles.tools.analyzer.gpib=0;
handles.tools.analyzer.instr='none';
handles.measure_function='Function'; % 'LogFreq' or 'Ringdown'
set(handles.popupmenu_instrument,'Value',handles.instrument_num); % set the default
set(handles.button_measure,'Enable','off');
set(handles.button_measure,'String',handles.measure_function);

fprintf(1,'  \n%s, GUI for Resonator Measurement and Analyzer Data\n\n',handles.versionstr);

% %
% verify that the Instrument Control Toolbox and kpib are installed
kpibpath = which('kpib');
if isempty(kpibpath)
    fprintf(1,'res_meas: WARNING: kpib.m does not appear to be installed.\n');
    fprintf(1,'            kpib.m can be downloaded from the MATLAB File Exchange, File ID# 12051.\n');
else
    kpibver = kpib('version',0,0,0,0,0,0);
    fprintf(1,'res_meas: kpib.m version %s installed.\n',num2str(kpibver));
    if handles.verbose >= 2, fprintf(1, '          %s\n',kpibpath); end
    if kpibver < 4.38
        fprintf(1,'res_meas: WARNING: your kpib.m file is out of date.\n');
        fprintf(1,'            Install version 4.38 or higher for best results.\n');
        fprintf(1,'            kpib.m can be downloaded from the MATLAB File Exchange, File ID# 12051.\n');
    end
end

instctrlver.Version = [];
if ~isdeployed
    instctrlver = ver('instrument');
    if isempty(instctrlver)
        fprintf(1,'res_meas: The Instrument Control Toolbox does not appear to be installed.\n');
    else
        fprintf(1,'res_meas: Instrument Control Toolbox version %s installed.\n',instctrlver.Version);
    end
end

% disable the instrument functions if toolbox or kpib are missing
if (~isdeployed && isempty(instctrlver.Version)) || isempty(which('kpib'))
    fprintf(1,'          Instrument functions are disabled; Load/View/Save is ok.\n\n')
    %set(handles.button_measure,'Enable','off');
    set(handles.checkbox_newdata,'Enable','off');
    set(handles.button_sweep,'Enable','off');
    set(handles.button_grab,'Enable','off');
    %set(handles.popupmenu_instrument,'Enable','off');
    set(handles.menu_reset,'Enable','off');
end



% are we on the path? and why not?
if isempty(strfind(path,fp))
    fprintf(1,'res_meas: WARNING: res_meas.m does not appear to be on the MATLAB path.\n');
    fprintf(1,'           You will get errors if you change the MATLAB directory\n');
    fprintf(1,'            while res_meas is running.\n');
    fprintf(1,'           Add this directory to the MATLAB path to avoid this issue.\n');
    fprintf(1,'\n');
end


% save the handles
guidata(hObject,handles)

fprintf(1,'res_meas: Ready. Select instrument.\n');

%%%% End Initialize
%------------------


%%%%%%%%%%%%%%%%%
% these items initialize the fields in the figure

% --- Executes during object creation, after setting all properties.
function field_center_1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to field_center_1 (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


% --- Executes during object creation, after setting all properties.
function field_span_1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to field_span_1 (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


% --- Executes during object creation, after setting all properties.
function popupmenu_instrument_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_instrument (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



% --- Executes during object creation, after setting all properties.
function field_peak_freq_CreateFcn(hObject, eventdata, handles)
% hObject    handle to field_peak_freq (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


% --- Executes during object creation, after setting all properties.
function field_q_CreateFcn(hObject, eventdata, handles)
% hObject    handle to field_q (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


% % --- Executes during object creation, after setting all properties.
% function field_bandwidth_CreateFcn(hObject, eventdata, handles)
% % hObject    handle to field_bandwidth (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
%     set(hObject,'BackgroundColor','white');
% else
%     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
% end


% --- Executes during object creation, after setting all properties.
function field_peak_amp_CreateFcn(hObject, eventdata, handles)
% hObject    handle to field_peak_amp (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


%-------------------------
% Begin User GUI Code here
%-------------------------


%-------------------------
% Menus


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


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

% allow user to save the plot data
% data is saved in a binary .mat file. Basically, just save the handles.res
%  variable. This includes much more data than the text file.

verbose=handles.verbose;

% supply a default filename
datapath=[handles.datapath '_res_' handles.datetime '.mat'];
% user can save either binary or ASCII text
%filetypes={datapath; '*.txt'};
% open dialog box for user to enter file name
[filename, pathname, filterindex]=uiputfile(datapath,'Save Data to .mat File');
% filepath will be empty if user presses cancel
if ~isequal(filename,0) && ~isequal(pathname,0)
    fp=[pathname filename];
    if ~isempty(handles.res)
        resdata=handles.res;
        save(fp, 'resdata');

        % save the path where user saved data
        handles.datapath=pathname;
	
        % save the handles
		guidata(hObject,handles)
        
        if verbose >= 1
            fprintf(1,'\n%s "%s"\n\n','res_meas: Data saved to file',filename);
        end
    else
            fprintf(1,'\n  %s\n\n','res_meas: Warning: No data to save! (handles.res empty)');
    end
else
    fprintf(1,'\n  %s\n\n','res_meas: Warning: No data saved.');
end





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

% allow user to save the trace data from the analyzer in an ASCII text file.
% data is saved in a text file with 4 columns: freq, amplitude, freq, phase
%   (yes, columns 1 and 3 should be identical)


% supply a default filename
datapath=[handles.datapath '_' handles.datetime '.txt'];
% open dialog box for user to enter file name
[filename, pathname, filterindex]=uiputfile(datapath,'Save Data to .txt File');
% filepath will be empty if user presses cancel
if ~isequal(filename,0) && ~isequal(pathname,0)
    fp=[pathname filename];
    if ~isempty(handles.res)
        % assemble the data
        data=[];
        try
            if isfield(handles.res,'trace1')
                data=[data handles.res.trace1.x handles.res.trace1.y];
            end
            if isfield(handles.res,'trace2')
                data=[data handles.res.trace2.x handles.res.trace2.y];
            end
            if isfield(handles.res,'trace3')
                data=[data handles.res.trace3.x handles.res.trace3.y];
            end
            if isfield(handles.res,'trace4')
                data=[data handles.res.trace4.x handles.res.trace4.y];
            end
            
            save(fp, 'data', '-ASCII');
            % save the path where user saved data
            handles.datapath=pathname;

            % save the handles
            guidata(hObject,handles)
            
            fprintf(1,'\n  %s\n\n','res_meas: Data saved to text file.');
        
        catch
            fprintf(1,'res_meas: ERROR: Data not saved. The length of all data sets must be the same.\n');
            fprintf(1,'                 Try saving as a binary file (.mat) using "File/Save Data".\n\n');
        end
    
    else
        fprintf(1,'\n  %s\n\n','res_meas: Warning: No data to save! (handles.res empty)');
    end
else
    fprintf(1,'\n  %s\n\n','res_meas: Warning: No data saved.');
end





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

% save the current figure as a matlab .fig file

% get the path that the user used most recently
datapath=handles.datapath;
% Note: res_meas must be on the MATLAB path
%  because the datapath will typically change the directory from the
%  starting directory where res_meas is located
if handles.usedatapath > 0
    cd(datapath);
end

% supply a default filename
defname=[handles.datapath '_Plot_' handles.datetime];
% file types: .fig file or .png
filetypes={'*.png' 'PNG file (*.png)'; '*.fig' 'MATLAB figure (*.fig)'; '*.tif' 'TIFF file (*.tif)'};
%filetypes={'*.fig' 'MATLAB figure (*.fig)'};
% open dialog box for user to enter file name
[filename, pathname, filterindex]=uiputfile(filetypes,'Save Plot to File',defname);
% filepath will be empty if user presses cancel
if ~isequal(filename,0) && ~isequal(pathname,0)
    fp=[pathname filename];
    switch filterindex
        case 1
            saveas(gcf,fp,'png');
        case 2
            saveas(gcf,fp,'fig');
        case 3
            saveas(gcf,fp,'tif');
    end
    fprintf(1,'res_meas: graphics file saved.\n\n');

    % save the path where user saved data
    handles.datapath=pathname;

    % save the handles
    guidata(hObject,handles)

else
    fprintf(1,'res_meas: Warning: No plot saved.\n\n');
end


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

% allow user to load a previously saved plot data file
% data is saved as a binary .mat file OR as a ASCII text file
% In a binary file, there should be one variable, a struct, with many fields.
%  We just assign this struct to handles.res
% In a text file, there are 4 columns: freq, amplitude, freq, phase
%   (yes, columns 1 and 3 should be identical)

% get the path that the user used most recently
datapath=handles.datapath;
% Note: res_meas must be on the MATLAB path
%  because the datapath will typically change the directory from the
%  starting directory where res_meas is located
if handles.usedatapath > 0
    try
        cd(datapath);
    catch
        datapath=pwd;
    end
end
% file types: binary and ASCII
filetypes={'*.mat' 'MAT-file (*.mat)'; '*.txt' 'ASCII text file (*.txt)'; '*.csv' 'ASCII CSV file (*.csv)'};
% dialog box for choosing a file
%[filename, pathname]=uigetfile([datapath '{*.*}'],'Choose a File to Load')
[filename, pathname]=uigetfile(filetypes,'Choose a File to Load');
% filepath will be empty if user presses cancel
if ~isequal(filename,0) && ~isequal(pathname,0);

    % clear the res data
    handles.res=[];
    filedata=load([pathname filename]);
    
    % % Load a binary file
    if isstruct(filedata) % we are loading a binary file
        if isfield(filedata,'myres') % if it is a mux-TCf file
            resntr = filedata.myres.resntr;
        elseif isfield(filedata,'resntr') % TCf_res
            resntr = filedata.resntr;
        elseif isfield(filedata,'oscltr') % TCf_osc
            resntr = filedata.oscltr;
        else % a single resonator file
            filedatanames=fieldnames(filedata);
            %handles.res=filedata.(filedatanames{1});
            resntr=filedata.(filedatanames{1});
        end

        
        if length(resntr) > 1
            [msteps, ld] = size(resntr); % rows are temp. steps, cols are repeated measurements
            % ask the user which measurement to load
            mprompt = {['Measurement Step # (1-' num2str(msteps) '):'],...
                        ['Individual Measurement # (1-' num2str(ld) '):']};
            measnumber = inputdlg(mprompt,'Choose a Measurement to Display',1,{'1','1'});
            handles.res=resntr(str2num(measnumber{1}),str2num(measnumber{2}));
            % print status message
            fprintf(1,'\nres_meas: data (%d,%d) loaded from binary file:\n',str2num(measnumber{1}),str2num(measnumber{2}));
        
        else
            handles.res=resntr;
            % print status message
            if handles.verbose >= 1, fprintf(1,'res_meas: data loaded from binary file "%s"\n',filename); end
        end

        
        % %% %
        % update binary file?
        if strcmpi(handles.updatefiles,'on')

            % V_bias is now Vbias_set or Vbias_read
            if isfield(handles.res,'V_bias')
                handles.res.Vbias_set=handles.res.V_bias;
                handles.res=rmfield(handles.res,'V_bias');
            end
            % source.level is deprecated
            if isfield(handles.res,'source')
                if isstruct(handles.res.source) && isfield(handles.res.source,'level') % old school
                    slevel=handles.res.source.level;
                    handles.res=rmfield(handles.res,'source');
                    handles.res.source=slevel;
                end
            end
            % motional is superseded by equ_circuit
            %if isfield(handles.res,'motional')
            %    handles.res=rmfield(handles.res,'motional');
            %end

            % ask for missing fields
            handles.res = rgetfields(handles.res);

            % run bandqr
            %[handles.res.bandwidth handles.res.Q handles.res.equ_circuit handles.res.db handles.res.phase_shift handles.res.Hn handles.res.dbfreq]=bandqr(handles.res);
            % fix units (older files)
            handles.res = rfixunits(handles.res);

            % print status message
            fprintf(1,'res_meas: Data has been updated. Use File->Save to save the updated data.\n');
        end


        
    % % Load a text file
    else % we are loading an ASCII file
        % assign the data to the appropriate variables
        [trows, tcols] = size(filedata);
        handles.res.trace1.x=filedata(:,1);
        handles.res.trace1.y=filedata(:,2);
        if tcols > 3
            handles.res.trace2.x=filedata(:,3);
            handles.res.trace2.y=filedata(:,4);
        end
        if tcols > 5
            handles.res.trace3.x=filedata(:,5);
            handles.res.trace3.y=filedata(:,6);
        end
        if tcols > 7
            handles.res.trace4.x=filedata(:,7);
            handles.res.trace4.y=filedata(:,8);
        end
        if tcols==4 % assume resonator data
%             handles.res.mark1.y=max(filedata(:,2));
%             m1x=find(filedata(:,2)==max(filedata(:,2)));
%             handles.res.mark1.x=filedata(m1x(1),1);
%             handles.res.mark2.x=handles.res.mark1.x;
%             handles.res.mark2.y=filedata(m1x(1),3);
            
            % update file?
            if strcmpi(handles.updatefiles,'on')
                handles.res = rgetfields(handles.res);
            end

            % estimate Q
            %[handles.res.bandwidth handles.res.Q handles.res.equ_circuit handles.res.db handles.res.phase_shift handles.res.Hn handles.res.dbfreq]=bandqr(handles.res);
        end

            
        % print status message
        fprintf(1,'res_meas: data loaded from text file "%s":\n',filename);
        
    end
    
    % save the path where user loaded data
    handles.datapath=pathname;
    %disp(handles.datapath)

    % uncheck the "get new" checkbox
    minVal = get(handles.checkbox_newdata,'Min'); 
    set(handles.checkbox_newdata,'Value',minVal);
    handles.get_new=0;
    
    % save the handles
	guidata(hObject,handles)
	
	% display the data
	showdata(hObject, eventdata, handles);
    
    % put data in workspace
	assignin('base','trace_load',handles.res);
    res=handles.res;
    
    % print a status message
    fprintf(1,' Measurement data saved in the workspace variable "trace_load".\n');
    fprintf(1,'\n\n');
    
end



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

% quits the program
fprintf(1,'res_meas: program quit.\n\n');
%kpib(handles.tools.analyzer,'label','',0,0,handles.verbose);


delete(handles.figure1);


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

% show the GPIB address 
set(handles.menu_gpibaddr,'Label',['Analyzer GPIB address: ' num2str(handles.tools.analyzer.gpib)]);

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

% allow the user to change the zoom in scans (span2 and span3)
% cell arrays for the dialog box - use the values for the defaults to
% "remember" settings
span_prompt={'2nd span width (Hz):','Final span width (Hz)',...
    'Number of Averages/Seconds to Wait:','Verbose Level (0,1,2)',...
    'Vbias Instrument Name','Vbias Instrument GPIB Address','Vbias Instrument Channel',...
    'Amplifier Gain','Update Files When Loaded (on|off)'};
span_default={num2str(handles.span2),num2str(handles.span3),...
    num2str(handles.avewait),num2str(handles.verbose),...
    handles.tools.biasset.instr,num2str(handles.tools.biasset.gpib),num2str(handles.tools.biasset.channel),...
    num2str(handles.amp_gain),handles.updatefiles};
% dialog box
spans=inputdlg(span_prompt,'Measurement Settings',1,span_default);

% save the data
% if user presses cancel, spans will have no members
if length(spans)>0
	handles.span2=str2num(spans{1});
	handles.span3=str2num(spans{2});
	handles.avewait=str2num(spans{3});
    handles.verbose=str2num(spans{4});
    handles.tools.biasset.instr=spans{5};
    handles.tools.biasset.gpib=str2num(spans{6});
    handles.tools.biasset.channel=str2num(spans{7});
    handles.amp_gain=str2num(spans{8});
    handles.updatefiles=spans{9};
end


% save the handles
guidata(hObject,handles)



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

% set the averaging on or off with a checked menu
checkmark=get(handles.menu_averaging,'Checked');
%length(checkmark)
% can't compare 'off' and 'on'?
if length(checkmark) > 2
    set(handles.menu_averaging,'Checked','on');
    handles.use_averaging='On';
    if handles.verbose >= 2, fprintf(1,'res_meas: Averaging ON.\n'); end
else
    set(handles.menu_averaging,'Checked','off');
    handles.use_averaging='Wait';
    if handles.verbose >= 2, fprintf(1,'res_meas: Averaging OFF.\n'); end
end

% save the handles
guidata(hObject,handles)


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

% dialog box
gpib_prompt={'Enter the GPIB address of the Analyzer:'};
gpib_default={num2str(handles.tools.analyzer.gpib)};
gpib_set=inputdlg(gpib_prompt,'GPIB Address',1,gpib_default);

% save the data
% if user presses cancel, result will have no members
if ~isempty(gpib_set)
	handles.tools.analyzer.gpib=str2num(gpib_set{1});
    % enable all measurement buttons. They will be disabled as necessary.
    set(handles.button_measure,'Enable','on');
    set(handles.button_sweep,'Enable','on');
    set(handles.button_grab,'Enable','on');
    set(handles.checkbox_newdata,'Enable','on');
end

% save the handles
guidata(hObject,handles)

if handles.verbose >= 1
    fprintf(1,'res_meas: Analyzer GPIB Address set to: %d\n\n', handles.tools.analyzer.gpib);
end

% is analyzer at this address?
fprintf(1,'  GPIB address set to %d.\n',handles.tools.analyzer.gpib);
if isequal(handles.tools.analyzer.instr,'HP_4195A') % 4195A does not support *IDN?
    instrstr = -1;
else
	instrstr = ridentify(handles.tools.analyzer.gpib);
end
if instrstr == 0 % no instrument detected
    % uncheck the "get new" checkbox
    minVal = get(handles.checkbox_newdata,'Min'); 
    set(handles.checkbox_newdata,'Value',minVal);
    handles.get_new=0;
    % disable buttons used with intruments
    set(handles.button_sweep,'Enable','off');
    set(handles.button_grab,'Enable','off');
    set(handles.checkbox_newdata,'Enable','off');
end


% %% menu_updatefiles_Callback
% % --------------------------------------------------------------------
% function menu_updatefiles_Callback(hObject, eventdata, handles)
% % hObject    handle to menu_updatefiles (see GCBO)
% % eventdata  reserved - to be defined in a future version of MATLAB
% % handles    structure with handles and user data (see GUIDATA)
% 
% % set whether we update binary files when they are loaded
% %  on or off with a checked menu
% checkmark=get(handles.menu_updatefiles,'Checked');
% % can't compare 'off' and 'on'?
% switch checkmark
%     case 'off' % if it was off, turn it on
%         set(handles.menu_updatefiles,'Checked','on');
%         handles.updatefiles='on';
%         if handles.verbose >= 2, fprintf(1,'res_meas: File updating ON.\n'); end
% 
%     case 'on' % if it was on, turn it off
%         set(handles.menu_updatefiles,'Checked','off');
%         handles.updatefiles='off';
%         if handles.verbose >= 2, fprintf(1,'res_meas: File updating OFF.\n'); end
% 
% end


% save the handles
guidata(hObject,handles)


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

% set the display of markers for peak and 3db points
%  on or off with a checked menu
checkmark=get(handles.menu_label_points,'Checked');
%length(checkmark)
% can't compare 'off' and 'on'?
if length(checkmark) > 2
    set(handles.menu_label_points,'Checked','on');
    handles.label_points='on';
    if handles.verbose >= 2, fprintf(1,'res_meas: Key Point labels ON.\n'); end
else
    set(handles.menu_label_points,'Checked','off');
    handles.label_points='off';
    if handles.verbose >= 2, fprintf(1,'res_meas: Key Point labels OFF.\n'); end
end

if isfield(handles,'res')
	% replot the data
	showdata(hObject, eventdata, handles);
end
    
% save the handles
guidata(hObject,handles)


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

% set whether we load center/span from analyzer or from user settings
%  on or off with a checked menu
checkmark=get(handles.menu_get_set,'Checked');
% can't compare 'off' and 'on'?
switch checkmark
    case 'off' % if it was off, turn it on
        set(handles.menu_get_set,'Checked','on');
        handles.get_set='on';
        % indicate that the values come from the analyzer
        set(handles.field_center_1,'String','[analyzer]');
        set(handles.field_span_1,'String','[analyzer]');
        
        if handles.verbose >= 2, fprintf(1,'res_meas: Get Settings from Analyzer ON.\n'); end
        
    case 'on' % if it was on, turn it off
        set(handles.menu_get_set,'Checked','off');
        handles.get_set='off';
        % reset the values displayed in the measurement fields
        center1=get(handles.field_center_1,'Value');
		set(handles.field_center_1,'String',num2str(center1,'%.0f'));
		
		span1=get(handles.field_span_1,'Value');
		set(handles.field_span_1,'String',num2str(span1,'%.0f'));
        
        if handles.verbose >= 2, fprintf(1,'res_meas: Get Settings from Analyzer OFF.\n'); end
end


% save the handles
guidata(hObject,handles)



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

% set whether we plot new data on top of old, or clear the plot each time
%  on or off with a checked menu
checkmark=get(handles.menu_plothold,'Checked');
% can't compare 'off' and 'on'?
switch checkmark
    case 'off' % if it was off, turn it on
        set(handles.menu_plothold,'Checked','on');
        handles.plothold=1;
        if handles.verbose >= 2, fprintf(1,'res_meas: Plot Hold ON.\n'); end
    case 'on' % if it was on, turn it off
        set(handles.menu_plothold,'Checked','off');
        handles.plothold=0;
        %handles.paxes = [];
        if handles.verbose >= 2, fprintf(1,'res_meas: Plot Hold OFF.\n'); end
end

% save the handles
guidata(hObject,handles)



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

hp1=sprintf('%s\n\nCapactive Feedthrough Extraction\nSteps:\n',handles.versionstr);
hp2=sprintf('1) use res_meas to measure a resonator. Save the data to a file.\n');
hp3=sprintf('%s\n    %s\n','2) Turn the bias off and measure again over the same frequency range',...
    '(this is a measurement of the feedthrough capacitance signal).');
hp4=sprintf('%s\n    %s\n','3) Select this menu item and choose "Do Extraction".',...
    'You will be prompted to select the saved measurement file for the resonator from Step 1.');
hp5=sprintf('\n%s\nIf you have not yet performed Step 2, close this window.');
helpstring=[hp1 hp2 hp3 hp4 hp5];
button = questdlg(helpstring,'Feedthrough Extraction','Do Extraction','Close this window','Close this window');

if strcmp(button,'Do Extraction')
    
    trace_meas=handles.res;
    
    % load the previous measurement of the resonator
    trace_load=menu_load_Callback(hObject, eventdata, handles)
    %trace_load=handles.res;


    % do the resonator extraction based on the existing variables
    res_extr=feedthru(trace_load,trace_meas);

    % handle older format
    if isfield(trace_load,'motional')
        trace_load.equ_circuit=trace_load.motional;
    end
    if isfield(trace_meas,'motional')
        trace_meas.equ_circuit=trace_meas.motional;
    end

    %%
    % plot
    xfreq=trace_load.trace1.x; % all plots use the x-axis from total response
    ftplot=figure;
    % plot magnitude
    subplot (2,1,1); hold on;
    plot(xfreq,trace_load.trace1.y,'-b');
    plot(xfreq,trace_meas.trace1.y,'-g');
    plot(xfreq,res_extr.trace1.y,'.-k');
    pmarkeramp=plot(res_extr.mark1.x,res_extr.mark1.y,'dr');
    title('Magnitude')
    xlabel('Frequency (Hz)');
    ylabel('Magnitude (dB)');
    legend('Measured','Feedthrough','Extracted',3);
    grid on;
    % plot phase
    subplot(2,1,2); hold on;
    plot(xfreq,trace_load.trace2.y,'-b');
    plot(xfreq,trace_meas.trace2.y,'-g');
    plot(xfreq,res_extr.trace2.y,'.-k');
    pmarkerphs=plot(res_extr.mark2.x,res_extr.mark2.y,'dr');
    title('Phase')
    xlabel('Frequency (Hz)');
    ylabel('Phase (deg)');
    legend('Measured','Feedthrough','Extracted',3);
    grid on;

    % print some results to the workspace
    fprintf('\nres_feed: results: [extracted (measured)]\n\n');

    fprintf(1,' Peak Frequency: %.0f Hz (%.0f)\n',res_extr.mark1.x,trace_load.mark1.x);
    fprintf(1,'      Amplitude: %.3f dB (%.3f)\n',res_extr.mark1.y,trace_load.mark1.y);
    fprintf(1,'              Q: %.0f (%.0f)\n',res_extr.Q,trace_load.Q);
    fprintf(1,'  3db Bandwidth: %.0f Hz (%.0f)\n',res_extr.bandwidth,trace_load.bandwidth);
    fprintf(1,'    Phase shift: %.0f deg',res_extr.phase_shift);
    if isfield(trace_load,'phase_shift')
        fprintf(1,' (%.0f)\n',trace_load.phase_shift);
    else
        fprintf(1,'\n');
    end
    if isfield(res_extr,'amp_gain') && isfield(trace_load,'equ_circuit')
        fprintf(1,' Motional Resistance for a gain of %g:\n',res_extr.amp_gain);
        fprintf(1,'                 %g ohms (%g)\n',res_extr.equ_circuit(1),trace_load.equ_circuit(1));
        fprintf(1,' Feedthrough Capacitance for a gain of %g:\n',res_extr.amp_gain);
        fprintf(1,'                 %g F (%g)\n',res_extr.equ_circuit(2),trace_load.equ_circuit(2));
    end

    fprintf(1,'\nres_feed: Results saved in the variable "res_extr".\n\n');


    
    
end






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


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

% the About menu
datestr=date;
yearstr=datestr(8:11);
aboutstring=sprintf('%s\nA GUI for Resonator Measurement and\n  Analyzer Data\nBy M.A. Hopcroft, hopcroft@mems.stanford.edu\nCopyright %s',handles.versionstr,yearstr);
helpdlg(aboutstring,'About res_meas');


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

% the Help menu

hp1=sprintf('%s\n\nClick the button below to open the .pdf Help File.\nQuick Tips:\n',handles.versionstr);
hp2=sprintf('Information and Status messages are printed in the Command Window.\n');
hp3=sprintf('If GPIB connections seem faulty, try Help->Reset GPIB.\n');
hp4=sprintf('To change the type of analysis, select a different analyzer from the drop-down menu (Scope or Network).\n');
hp5=sprintf('For help with res_feed, type "help res_feed" at the command prompt.\n');
helpstring=[hp1 hp2 hp3 hp4 hp5];
button = questdlg(helpstring,'res_meas Help','Open Help file','Close this window','Close this window');

if strcmp(button,'Open Help file')
    [fid, ferror] = fopen('res_meas_help.pdf');
    if fid ~= -1
        open('res_meas_help.pdf');
    else
        fprintf('res_meas: Help file "res_meas_help.pdf" is missing (%s)\n',ferror);
    end
end


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

% do we have a recent version of kpib?
kpibver = kpib('version',0,0,0,0,0,0);
if kpibver >= 4.8
    % scan the GPIB bus
    fprintf(1,'res_meas: Detected GPIB Adaptors and Instruments:\n');
    kpib('scan',0,'identify',0,0,0,handles.verbose);
else
    fprintf(1,'res_meas: kpib.m version 4.8 or later required for ''scan'' (you have %g).\n',kpibver);
end

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

% reset GPIB connections
kpib('clear',0,0,0,0,0,handles.verbose);



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

% clears the data saved in handles.res and the data in the workspace
handles.res=[];
assignin('base','trace_meas',handles.res);
assignin('base','trace_load',handles.res);
% clear the plot
cla(handles.axes1,'reset');
cla(handles.axes2,'reset');

fprintf(1,'res_meas: Data cleared from memory and workspace.\n');

% save the handle data
guidata(hObject,handles)




% %% %% %% %% %% %% %% %% %% %% %% %% %
%-------------------------
% Buttons

%% popupmenu_instrument_Callback
% --- Executes on selection change in popupmenu_instrument.
function popupmenu_instrument_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu_instrument (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 popupmenu_instrument contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_instrument

instrument_num=get(handles.popupmenu_instrument,'Value');
handles.instrument_num=instrument_num; % save the choice
set(handles.popupmenu_instrument,'Value',instrument_num);
fprintf(1,'res_meas:\n');
% enable all measurement buttons. They will be disabled as necessary.
set(handles.button_measure,'Enable','on');
set(handles.button_sweep,'Enable','on');
set(handles.button_grab,'Enable','on');
set(handles.checkbox_newdata,'Enable','on');

% print a status message about the instrument change.
% set the default GPIB address for the new instrument.
% set other defaults as typical.
switch instrument_num
    case 1
        handles.tools.analyzer.gpib=0; 
        handles.tools.analyzer.instr='none';
        handles.measure_function='Function';
        set(handles.button_measure,'String',handles.measure_function);
        set(handles.button_measure,'Enable','off');
        fprintf(1,'  No instrument selected.\n');
    case 2
        handles.tools.analyzer.instr='HP_89410A';
        handles.tools.analyzer.gpib=16;
        set(handles.menu_averaging,'Checked','on'); handles.use_averaging='on';
        handles.measure_function='LogFreq';
        fprintf(1,'  Analyzer changed to HP 89410A Vector Signal Analyzer.\n');
    case 3
        handles.tools.analyzer.instr='HP_4395A';
        handles.tools.analyzer.gpib=17;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        handles.measure_function='LogFreq';
        fprintf(1,'  Analyzer changed to HP 4395A Network/Spectrum Analyzer.\n');
    case 4
        handles.tools.analyzer.instr='HP_8753ES';
        handles.tools.analyzer.gpib=19;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        handles.measure_function='LogFreq';
        fprintf(1,'  Analyzer changed to HP 8753ES S-Parameter Network Analyzer.\n');
    case 5
        handles.tools.analyzer.instr='HP_4195A';
        handles.tools.analyzer.gpib=7;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        handles.measure_function='LogFreq';
        fprintf(1,'  Analyzer changed to HP 4195A Network/Spectrum Analyzer.\n');
    case 6
        handles.tools.analyzer.instr='AG_E5071B';
        handles.tools.analyzer.gpib=15;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        handles.measure_function='LogFreq';
        fprintf(1,'  Analyzer changed to AG E5071B Network/Spectrum Analyzer.\n'); 
    case 7
        handles.tools.analyzer.instr='HP_8560A';
        handles.tools.analyzer.gpib=15;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        fprintf(1,'  Analyzer changed to HP 8560A Spectrum Analyzer.\n');
        fprintf(1,'  NOTE: Only Grab function is supported for this Analyzer.\n');
        handles.measure_function='LogFreq';
        % disable buttons
        set(handles.button_measure,'Enable','off');
        set(handles.button_sweep,'Enable','off');
    case 8
        handles.tools.analyzer.instr='TEK_TDS';
        handles.tools.analyzer.gpib=5;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        fprintf(1,'  Analyzer changed to Tektronix TDS family Oscilloscope.\n');
        %fprintf(1,'  NOTE: Only Grab function is supported for this Oscilloscope.\n');
        handles.measure_function='Ringdown';
        % disable buttons
        %set(handles.button_measure,'Enable','off');
        set(handles.button_sweep,'Enable','off');
    case 9
        handles.tools.analyzer.instr='HP_54600';
        handles.tools.analyzer.gpib=8;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        fprintf(1,'  Analyzer changed to HP 54600 Series Oscilloscope.\n');
        %fprintf(1,'  NOTE: Only Grab function is supported for this Oscilloscope.\n');
        handles.measure_function='Ringdown';
        % disable buttons
        %set(handles.button_measure,'Enable','off');
        set(handles.button_sweep,'Enable','off');
    case 10
        handles.tools.analyzer.instr='HP_54800';
        handles.tools.analyzer.gpib=7;
        set(handles.menu_averaging,'Checked','off'); handles.use_averaging='off';
        fprintf(1,'  Analyzer changed to HP 54800 Series (Infiniium) Oscilloscope.\n');
        %fprintf(1,'  NOTE: Only Grab function is supported for this Oscilloscope.\n');
        handles.measure_function='Ringdown';
        % disable buttons
        %set(handles.button_measure,'Enable','off');
        set(handles.button_sweep,'Enable','off');        
end

% set the measure button to the appropriate function
set(handles.button_measure,'String',handles.measure_function);


% is the new analyzer connected?
fprintf(1,'  GPIB address set to %d.\n',handles.tools.analyzer.gpib);
if any(strcmpi(handles.tools.analyzer.instr,{'none','HP_4195A'})) % 4195A does not support *IDN?
    instrstr = -1;
else
	instrstr = ridentify(handles.tools.analyzer.gpib);
end
if instrstr == 0 % no instrument detected
    % uncheck the "get new" checkbox
    minVal = get(handles.checkbox_newdata,'Min'); 
    set(handles.checkbox_newdata,'Value',minVal);
    handles.get_new=0;
    % disable buttons used with intruments
    set(handles.button_sweep,'Enable','off');
    set(handles.button_grab,'Enable','off');
    set(handles.checkbox_newdata,'Enable','off');
end


% save the handle data
guidata(hObject,handles)


%% checkbox_newdata
% --- Executes on button press in checkbox_newdata.
function checkbox_newdata_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_newdata (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 checkbox_newdata

if (get(hObject,'Value') == get(hObject,'Max'))
	% Checkbox is checked-take approriate action
    maxVal = get(handles.checkbox_newdata,'Max'); 
    set(handles.checkbox_newdata,'Value',maxVal);
    handles.get_new=1;
else
	% Checkbox is not checked-take approriate action
    minVal = get(handles.checkbox_newdata,'Min'); 
    set(handles.checkbox_newdata,'Value',minVal);
    handles.get_new=0;
end

% save the handles
guidata(hObject,handles)



%% field_center_1_Callback
% --- Executes on modification of the field_center_1 field
function field_center_1_Callback(hObject, eventdata, handles)
% hObject    handle to field_center_1 (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 field_center_1 as text
%        str2double(get(hObject,'String')) returns contents of field_center_1 as a double
%disp('field_center_1 callback')

% save what the user has typed in the box
center1=get(handles.field_center_1,'String');
set(handles.field_center_1,'Value',str2num(center1));

% unset the "Get Settings From Analyzer" setting
checkmark=get(handles.menu_get_set,'Checked');
if strcmpi(checkmark,'on') % if it was on, turn it off
    set(handles.menu_get_set,'Checked','off');
    handles.get_set='off';
    % reset the value of center
    center1=get(handles.field_center_1,'Value');
    set(handles.field_center_1,'String',num2str(center1));
end

% save the handle data
guidata(hObject,handles)


%% field_span_1_Callback
% --- Executes on modification of the field_span_1 field
function field_span_1_Callback(hObject, eventdata, handles)
% hObject    handle to field_span_1 (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 field_span_1 as text
%        str2double(get(hObject,'String')) returns contents of field_span_1 as a double
%disp('field_span_1 callback')

% save what the user has typed in the box
span1=get(handles.field_span_1,'String');
set(handles.field_span_1,'Value',str2num(span1));

% unset the "Get Settings From Analyzer" setting
checkmark=get(handles.menu_get_set,'Checked');
% can't compare 'off' and 'on'?
if strcmpi(checkmark,'on') % if it was on, turn it off
 % if it was on, turn it off
    set(handles.menu_get_set,'Checked','off');
    handles.get_set='off';
    % reset the value of span
    span1=get(handles.field_span_1,'Value');
    set(handles.field_span_1,'String',num2str(span1,'%.0f'));
end

% save the handle data
guidata(hObject,handles)


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

%disp('measuring...')
res=[];
verbose=handles.verbose;
% execute the apprpriate measurement function
switch handles.measure_function
    case 'Ringdown'
        if verbose >= 1
            fprintf(1,'res_meas: Analyze Ringdown data...\n');
            if verbose < 2
                fprintf(1,'         (increase VERBOSE level for more details)\n');
            end
        end
        res=analyze_ringdown(hObject, eventdata, handles);
    case 'LogFreq'
        if verbose >= 1, fprintf(1,'res_meas: Analyze Resonator Bode plot...\n'); end
        res=measure_resonator(hObject, eventdata, handles);
    otherwise
        if verbose >= 1, fprintf(1,'res_meas: Select an instrument to enable measurement functions...\n'); end
end

if isempty(res)
    if verbose >= 1, fprintf(1,'res_meas: Measurement Error.\n'); end
end

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

% this button resets the instrument to a "scanning mode", i.e.,
% the sort of settings an operator would use to manually find a peak:
%  continuous sweep, 5db/div, center=initial center, span=initial span

%disp('sweeping...')

verbose=handles.verbose;

% get the parameters for the measurement
tools.analyzer=handles.tools.analyzer;
instrument=get(handles.popupmenu_instrument,'Value');

% reset the instrument to the starting center/span values
%   or use the values that the instrument is set for

center1=get(handles.field_center_1,'Value');
%set(handles.field_center_1,'Value',str2num(center1));

span1=get(handles.field_span_1,'Value');
%set(handles.field_span_1,'Value',str2num(span1));
    
% span2=handles.span2;
% span3=handles.span3;
% avewait=handles.avewait;
% average_on=handles.use_averaging;

if verbose >= 1, fprintf(1,'%s %.0f %s %.0f ...\n','res_meas: sweeping: Center:',center1,'Span:',span1); end

pause(1);
failm = 0;

try
    
    % make sure we are on channel 1
    kpib(tools.analyzer,'channel',1,0,0,verbose);
    % put a label on the Analyzer screen
    kpib(tools.analyzer,'label','Sweeping',0,0,verbose);
    kpib(tools.analyzer,'center',center1,0,0,verbose);
    kpib(tools.analyzer,'span',span1,0,0,verbose);
    kpib(tools.analyzer,'scale',5,1,0,verbose);
    kpib(tools.analyzer,'average','off',0,0,verbose);
    kpib(tools.analyzer,'continue',0,0,0,verbose);
    % wait until command is complete
    kpib(tools.analyzer,'complete','single',0,0,verbose);
    % Autoscale the display
    %kpib(tools.analyzer,'autoscale','once',0,0,verbose);
    % set the phase scale to 90
    kpib(tools.analyzer,'scale',90,2,0,verbose);
    % make sure we are on channel 1
    kpib(tools.analyzer,'channel',1,0,0,verbose);
    kpib(tools.analyzer,'label','Ready',0,0,verbose);
    % close the instrument so that operator can use it
    kpib('close',tools.analyzer.gpib,0,0,0,0,verbose);
    
    if verbose >= 1, fprintf(1,'%s\n','res_meas: sweep complete.'); end

catch % try sweep
    failm = 1;
    if verbose >= 1, fprintf(1,'%s\n','res_meas: sweep failed; check instrument.'); end
end % try sweep



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

% this button grabs the data from the analyzer without doing any measurements or
%  changing any settings. The user can then save the data if they wish.

%disp('grab...')

% use the grab function (v5)
res=[];
res=grab_data(hObject, eventdata, handles);

if isempty(res) && verbose>=1
    fprintf(1,'res_meas: Error downloading data from instrument.');
end




% %% %% %% %% %% %% %% %% %%
% % sub functions
% %% %% %% %% %% %% %% %% %%

%% function: grab_data
function res=grab_data(hObject, eventdata, handles)
% Downloads data from an instrument
%

% % clear the graph
% if handles.plothold==0, cla reset; end
% drawnow;

% get the parameters for the measurement
tools = handles.tools;  % v4.0 update

verbose=handles.verbose;

% get the parameters for the measurement
%tools.analyzer=handles.tools.analyzer; % v4.0 update
%instrument=get(handles.popupmenu_instrument,'Value');
% save the amplifier gain
res.amp_gain=handles.amp_gain;

if verbose >= 1, fprintf(1,'res_meas: grabbing data from %s...\n',handles.tools.analyzer.instr); end
kpib(tools.analyzer,'label','Download',0,0,verbose);

pause(1);
failm = 0;
% record the time of the measurement
meastime = rconvertdate(clock,'file');
% % v4.0 we still need multiple cases because the 89410 has 4 channels
% when grabbing data, we want to guess whether we are grabbing a resonator
%  measurement or some other data (spectrum, noise, etc). If we have two
%  channels displayed on the instrument, then assume a resonator, and
%  process the resulting data using bandqr. If not, then simply download
%  the data.


% % % %
% in V5, analyzers using "grab", should just download data, and not analyze
%  it. If the user wants analysis, they can push the button.
try
    switch tools.analyzer.instr
        case 'HP_89410A' % HP 89410A
%             % how many data channels are displayed?
            dstate=kpib(tools.analyzer,'display','query',0,0,verbose);
%             if bin2dec(dstate)==12 % assume the usual 2-channel setup for a resonator
%                 if verbose >= 1, fprintf(1,'res_meas: looks like resonator data\n'); end
%                 res.trace1 = kpib(tools.analyzer,'getdata',0,1,'pow',verbose);
%                 res.trace2 = kpib(tools.analyzer,'getdata',0,2,'angl',verbose);
%                 res.mark1 = kpib(tools.analyzer,'marker?',1,'auto',0,verbose);
%                 res.mark2 = kpib(tools.analyzer,'marker?',2,'auto',0,verbose);
%     %             res.units1.x = kpib('HP_89410A',tools.analyzer.gpib,'units','x',1,0,verbose);
%     %             res.units1.y = kpib('HP_89410A',tools.analyzer.gpib,'units','y',1,'pow',verbose);
%     %             res.units2.x = kpib('HP_89410A',tools.analyzer.gpib,'units','x',2,0,verbose);
%     %             res.units2.y = kpib('HP_89410A',tools.analyzer.gpib,'units','y',2,'angl',verbose);
                rsource = kpib(tools.analyzer,'source?',0,0,0,verbose); res.source=rsource.level;
% 
%                 % assume a resonator, calculate the characteristics
%                 [res.bandwidth res.Q res.equ_circuit res.db res.phase_shift res.Hn res.dbfreq]=bandqr(res);
% 
%             else % some other displays are active, just get all the data
                % just get all the data
                for cd=1:4
                    if str2num(dstate(cd))==1
                        if verbose >= 1, fprintf(1,'res_meas: grab data on channel %d...\n',cd); end
                        eval(['res.trace' num2str(cd) ' = kpib(tools.analyzer,''getdata'',0,' num2str(cd) ',0,verbose);']);
                        eval(['res.mark' num2str(cd) ' = kpib(tools.analyzer,''marker'',''query'',' num2str(cd) ',0,verbose);']);
                        %eval(['res.units' num2str(cd) '.x = kpib(''HP_89410A'',tools.analyzer.gpib,''units'',''x'',' num2str(cd) ',0,verbose);']);
                    end
                end
%             end
        % network analyzers
        case {'HP_4395A','HP_8753ES','HP_4195A','AG_E5071','AG_E5071B'}
%             % are both channels displayed?
            dstate=kpib(tools.analyzer,'display','dual','?',0,verbose);
%             %mode=kpib(tools.analyzer,'mode','query',0,0,verbose);
%             if dstate==1 % assume the usual 2-channel setup for a resonator
%             %if strcmp(mode,'NA') % assume network mode is for a resonator
%                 if verbose >= 1, fprintf(1,'res_meas: looks like resonator data\n'); end
%                 %kpib(tools.analyzer,'channel',1,0,0,verbose);
%                 res.mark1 = kpib(tools.analyzer,'marker','query',1,0,verbose);
%                 res.trace1 = kpib(tools.analyzer,'getdata',0,1,0,verbose);
% 
%                 %kpib(tools.analyzer,'channel',2,0,0,verbose);
%                 res.mark2 = kpib(tools.analyzer,'marker','query',2,0,verbose);
%                 res.trace2 = kpib(tools.analyzer,'getdata',0,2,0,verbose);
%                 % reset the active channel
%                 kpib(tools.analyzer,'channel',1,0,0,verbose);

                rsource = kpib(tools.analyzer,'source','?',0,0,verbose); res.source=rsource;

%                 % calculate the resonator characteristics
%                 [res.bandwidth res.Q res.equ_circuit res.db res.phase_shift res.Hn res.dbfreq]=bandqr(res);

%             else % some other data (e.g. spectrum)
                % if only one channel is displayed, it must be the active
                %  channel, so we can just download the data.
                % Note that no channel is specified in the kpib commands
                res.mark1 = kpib(tools.analyzer,'marker','query',0,0,verbose);
                res.trace1 = kpib(tools.analyzer,'getdata',0,0,0,verbose);
                if dstate==1
                    res.mark2 = kpib(tools.analyzer,'marker','query',0,0,verbose);
                    res.trace2 = kpib(tools.analyzer,'getdata',0,0,0,verbose);
                end
%             end

        case {'HP_8560A'} % has only one channel
            res.trace1 = kpib(tools.analyzer,'getdata',0,1,0,verbose);
            res.mark1 = kpib(tools.analyzer,'marker','query',1,0,verbose);

        case {'TEK_TDS'} % oscilloscope
            % how many data channels are displayed?
            dstate=kpib(tools.analyzer,'display','query',0,0,verbose);
            for cd=1:4
                if str2num(dstate(cd))==1
                    if verbose >= 1, fprintf(1,'res_meas: grab data on channel %d...\n',cd); end
                    eval(['res.trace' num2str(cd) ' = kpib(tools.analyzer,''getdata'',0,' num2str(cd) ',0,verbose);']);
                end
            end
            
        case {'HP_54600','HP_54800'} % oscilloscope
            % how many data channels are displayed?
            dstate=kpib(tools.analyzer,'display','query',0,0,verbose);
            for cd=1:4
                if str2num(dstate(cd))==1
                    if verbose >= 1, fprintf(1,'res_meas: grab data on channel %d...\n',cd); end
                    eval(['res.trace' num2str(cd) ' = kpib(tools.analyzer,''getdata'',0,' num2str(cd) ',0,verbose);']);
                end
            end
            for cd=1:4
                if str2num(dstate(cd))==1, kpib(tools.analyzer,'display','on',cd,0,verbose); end
            end        

        otherwise
            fprintf(1,' %s\n\n','res_meas: Cannot complete measurement: analyzer drivers not implemented yet.');
            failm = 1;
    end

    kpib(tools.analyzer,'label','Done',0,0,verbose); % clear the analyzer screen
    
catch % try grab
    fprintf(1,'res_meas: Error downloading data from %s.',tools.analyzer.instr);
    failm=1;
end % try grab



if ~failm

    % attempt to record the bias voltage
    biasv=biascheck(hObject, eventdata, handles);
    %biasv=-1;
    if biasv ~= 1776
        res.Vbias_set=biasv;
    end
    
    % save the time that the measurement occured
    handles.datetime=meastime;
    res.clock=clock;
    res.tools=tools;
    
	% save the returned data for other functions
	handles.res=res;
    
    % put data in workspace
	assignin('base','trace_meas',handles.res);
    fprintf(1,' Measurement data saved in the workspace variable "trace_meas".\n');
    fprintf(1,'\n');    

    % save the handles
	guidata(hObject,handles)
	
    % print status message
    %fprintf(1,'%s\n','res_meas: Data from instrument:');
    
    % display the data
    showdata(hObject, eventdata, handles);

    
    pause(1); kpib(tools.analyzer,'label','',0,0,verbose); % clear the analzyer screen
    
end



%% function: measure_resonator
function res=measure_resonator(hObject, eventdata, handles)
% Performs a measurement of a resonator using measure_res
%
res=[];
% % clear the graph
% if handles.plothold==0, cla reset; end
% drawnow;

% clear the output fields
%disp('clear')
set(handles.field_peak_freq,'Value',0);
set(handles.field_peak_freq,'String','');
set(handles.field_peak_amp,'Value',0);
set(handles.field_peak_amp,'String','');
% set(handles.field_bandwidth,'Value',0);
% set(handles.field_bandwidth,'String','');
set(handles.field_q,'Value',0);
set(handles.field_q,'String','');

if handles.get_new == 1 % get measurement data from analyzer

    % get the parameters for the measurement
    tools = handles.tools;  % v4.0 update

    avewait=handles.avewait;
    average_on=handles.use_averaging;
    verbose=handles.verbose;

    center1=get(handles.field_center_1,'Value');
    span1=get(handles.field_span_1,'Value');
    span2=handles.span2;
    span3=handles.span3;

    if strcmpi(handles.get_set,'on') % use the analyzer's settings
        % get the current center/span settings
        center1=kpib(tools.analyzer,'center','query',0,0,verbose);
        span1=kpib(tools.analyzer,'span','query',0,0,verbose);
        % set the stored values to the analyzer's settings
        set(handles.field_center_1,'Value',center1);
        set(handles.field_span_1,'Value',span1);
        % display them in the GUI with brackets to indicate the 
        set(handles.field_center_1,'String',['[' num2str(center1) ']']);
        set(handles.field_span_1,'String',['[' num2str(span1) ']']);
    end

    % if the user specifies a span smaller than the set spans, use only
    % the user's setting
    if span1 <= span2,
        spanlist=[span1 span3];
        if span1 <= span3
            spanlist=span1;
        end
    elseif span2 == span3
        spanlist=[span1 span2];
    else
        spanlist=[span1 span2 span3];
    end
    
    if verbose >= 1, fprintf(1,'%s \n','res_meas: measuring...'); end

    % measure the resonator, using measure_res
    %disp('meas')
    pause(1);
    failm = 0;

    % %% %
    % v4.0 - use measure_res
    try
        kpib(tools.analyzer,'label','Measuring',0,0,verbose);
        res = measure_res(tools,center1,spanlist,average_on,avewait,verbose);
        meastime = rconvertdate(clock,'file');
        kpib(tools.analyzer,'label','Ready',0,0,verbose);
        % save the time that the measurement occured
        handles.datetime=meastime;
        res.tools=tools;
    catch
        res = [];
        failm = 1; % indicate failure
    end

else % use existing data
    res = handles.res;
    failm = 0;
    
end % if get_new


if ~failm
    
    % save the amplifier gain
    res.amp_gain=handles.amp_gain;
    
    % run bandqr to compute the Rx value with the user specified gain
    %[res.bandwidth res.Q res.equ_circuit res.db res.phase_shift res.Hn res.dbfreq]=bandqr(res);
    res=bandqrR(res);
    
	% save the returned data for other functions
	handles.res=res;
    
    % put data in workspace
	assignin('base','trace_meas',handles.res);
    
    % save the handles
	guidata(hObject,handles)
	
    % print status message
    fprintf(1,'%s\n','res_meas: Resonator measurement:');
    
    % display the data
    showdata(hObject, eventdata, handles);
    
    % print status message
    fprintf(1,' Measurement data saved in the workspace variable "trace_meas".\n');
    fprintf(1,'\n');
    
else
	fprintf(1,'res_meas: Error during communication with Analyzer. No data returned.\n');
	fprintf(1,'          Try any/all of the following:\n');
	fprintf(1,'          a) Check Analyzer selection menu and Analyzer settings.\n');
	fprintf(1,'          b) Reset GPIB from the Help menu.\n');
	fprintf(1,'          c) Quit and restart res_meas.\n');
	fprintf(1,'          d) Increase the Verbose Level (under Measurement Parameters) and repeat measurement.\n');
    fprintf(1,'\n');
    
end


%% function: analyze_ringdown
function failm=analyze_ringdown(hObject, eventdata, handles)
% Get data from an oscilloscope and analyze for ringdown characteristics
%
% % clear the graph
% if handles.plothold==0, cla reset; end
% drawnow;

% get the parameters for the measurement
tools = handles.tools;  % v4.0 update
verbose=handles.verbose;
failm=0; fail_grab=0;
dmax = 1; % envelope noise filter threshold

if handles.get_new == 1 % get measurement data from analyzer
    res=[];
    % use the grab function to get the data from the oscilloscope (v5)
    res=grab_data(hObject, eventdata, handles);
    
    if ~isempty(res)
        handles.res=ringdownR(res,verbose,verbose);
        % save the handles
        guidata(hObject,handles)
        
        % display the data
        showdata(hObject, eventdata, handles);
    end

end

if handles.get_new == 0

    res=handles.res; % the existing data

    handles.res=ringdownR(res,verbose,verbose);
    %handles.res=res_ring

    % save the handles
	guidata(hObject,handles)
	
    % print status message
    fprintf(1,'%s\n','res_meas: Ringdown results:');
    
    % display the data
    showdata(hObject, eventdata, handles);
    
end



%% function: showdata
% % SHOWDATA computes the bandwidth and Q, and plots the data in the figure
% % window
function showdata(hObject, eventdata, handles)
% SHOWDATA(RES)
%
% SHOWDATA expects to find handles.res, where RES is a resonator
% measurement data structure such as returned by measure_res.
%

% clear the graph
if handles.plothold==0
    % set the figure to be the current axes
    %axes(handles.axes1);
    cla(handles.axes1,'reset');
    %axes(handles.axes2);
    cla(handles.axes2,'reset');
else
    hold on;
end


% retrieve the data
res=handles.res;
if isempty(res), fprintf(1,'res_meas: showdata error.'); end

% what instrument was used?
%instrument=get(handles.popupmenu_instrument,'Value');


% display the results in the appropriate gui boxes
% if we have grabbed not-a-resonator data, many fields will be missing
% clear the existing values
set(handles.field_peak_freq,'String','0000');
set(handles.field_peak_amp,'String','0000');
set(handles.field_q,'String','0000');

if isfield(res,'mark1')
    set(handles.field_peak_freq,'Value',res.mark1.x);
    set(handles.field_peak_freq,'String',num2str(res.mark1.x,'%.1f'));
    set(handles.field_peak_amp,'Value',res.mark1.y);
    set(handles.field_peak_amp,'String',num2str(res.mark1.y,'%.2f'));
end

if isfield(res,'Q')
    set(handles.field_q,'Value',res.Q);
    set(handles.field_q,'String',num2str(res.Q,'%.0f'));
end

if isfield(res,'fft_max')
    set(handles.field_peak_freq,'Value',res.fft_max);
    set(handles.field_peak_freq,'String',num2str(res.fft_max,'%.1f'));
end

% plot the data
% the figure is "handles. axes1/axes2"


% if we measured or grabbed a resonator (trace1 and trace2 only) then plot
%  like a resonator (amplitude and phase). Otherwise, just plot raw data.

% handle units - create a units1/units2
% default units is no units
units1.x=''; units1.y=''; units2.x=''; units2.y='';

% deal with units format
[res, units1, units2] = rfixunits(res);


% is this a resonator mag/phase plot?
if (isfield(res,'trace1') && isfield(res,'trace2') && isfield(res,'mark2') && ~(isfield(res,'trace3') || isfield(res,'trace4')))
    %disp('resonator'); res

    % plot resonator amplitude and phase on top of each other
    plot(handles.axes2,res.trace2.x,res.trace2.y,'-m','LineWidth',1);
    set(get(handles.axes2,'Ylabel'),'String',['Phase (' units2.y ')']);
    plot(handles.axes1,res.trace1.x,res.trace1.y,'-b','LineWidth',3);
    set(get(handles.axes1,'Ylabel'),'String',['Amplitude (' units1.y ')']);
    
    % fix the plots
    set(handles.axes2,'YAxisLocation','right',...
                   'Color','none',...
                   'XColor','k','YColor','m','Box','off',...
                   'FontSize',14,'FontWeight','demi','FontName','Arial');
    set(handles.axes1,'FontSize',14,'FontWeight','demi','FontName','Arial');

    % label the X axis
    if ~isempty(units1.x)
        xspan=res.trace1.x(end)-res.trace1.x(1);
        xstr=['Frequency (' units1.x ') [Span: ' num2str(xspan,'%.0f') ' ' units1.x ']'];
    else
        xstr='Frequency';
    end
    % is X log scale?
    if strfind(units1.x,'log'), set(handles.axes1,'XScale','log'); end
    if strfind(units2.x,'log'), set(handles.axes2,'XScale','log'); end
    
    % title
    set(get(handles.axes1,'Title'),'String','Resonator Data','FontSize',16,...
        'FontWeight','bold','FontName','Arial');

    
    
else % some other data, spectrum or scope
    %disp('resonator not'); res
    
    units.x=''; units.y='';  % default units is no units
    lstrings={''}; lcount=0;
    
    if isfield(res,'trace1')
        plot(handles.axes1,res.trace1.x,res.trace1.y,'.-b');
        hold(handles.axes1,'on');
         lcount=lcount+1;
         lstrings(lcount)={'Trace 1'};
         if isfield(res.trace1,'units')            
            units.x=res.trace1.units.x; units.y=res.trace1.units.y;
         end
    end
	if isfield(res,'trace2')
        plot(handles.axes1,res.trace2.x,res.trace2.y,'.-g');
        hold(handles.axes1,'on');
        lcount=lcount+1;
        lstrings(lcount)={'Trace 2'};
        if isfield(res.trace2,'units')
            units.x=res.trace2.units.x; units.y=res.trace2.units.y;
        end
    end
	if isfield(res,'trace3')
        plot(handles.axes1,res.trace3.x,res.trace3.y,'.-m');
        hold(handles.axes1,'on');
        lcount=lcount+1;
        lstrings(lcount)={'Trace 3'};
        if isfield(res.trace3,'units')
            units.x=res.trace3.units.x; units.y=res.trace3.units.y;
        end
    end
	if isfield(res,'trace4')
        plot(handles.axes1,res.trace4.x,res.trace4.y,'.-r');
        hold(handles.axes1,'on');
        lcount=lcount+1;
        lstrings(lcount)={'Trace 4'};
        if isfield(res.trace4,'units')
            units.x=res.trace4.units.x; units.y=res.trace4.units.y;
        end
    end
    legend(handles.axes1,lstrings,'Location','Best');
    
    % plot ringdown envelope
    if isfield(res,'env_upper')
        plot(handles.axes1,res.env_upper.x,res.env_upper.y,'.-m');
    end
    if isfield(res,'env_lower')
        plot(handles.axes1,res.env_lower.x,res.env_lower.y,'.-m');
    end   
    
    % axis labels
    set(get(handles.axes1,'Ylabel'),'String',['[' units.y ']']);
    xstr=['[' units.x ']'];

    % fix the plots
    set(handles.axes2,'Color','none','Box','off','XTick',[],'YTick',[])
    set(handles.axes1,'FontSize',14,'FontWeight','demi','FontName','Arial','Box','on');
    % is X log scale?
    if strfind(units1.x,'log'), set(handles.axes1,'XScale','log'); end

    
    % title
    set(get(handles.axes1,'Title'),'String','Instrument Data','FontSize',16,...
        'FontWeight','bold','FontName','Arial');
    
end





% axis labels
set(get(handles.axes1,'XLabel'),'FontSize',14,'FontWeight','bold','FontName','Arial',...
    'String',xstr);

set(get(handles.axes1,'YLabel'),'FontSize',14,'FontWeight','bold','FontName','Arial');
set(get(handles.axes2,'YLabel'),'FontSize',14,'FontWeight','bold','FontName','Arial');


hold(handles.axes1,'on');

% plot points, if selected
if strcmpi(handles.label_points,'on')
    if isfield(res,'mark1')
        % plot the center marker
        plot(handles.axes1,res.mark1.x,res.mark1.y,'dr','LineWidth',2);
    end
    if isfield(res,'db')
        % plot the 3dB bandwidth
        if ((res.db(1) > 0) && (res.db(2) > 0));
            plot(handles.axes1,res.trace1.x(res.db(1)),res.trace1.y(res.db(1)),'+r','LineWidth',2);
            plot(handles.axes1,res.trace1.x(res.db(2)),res.trace1.y(res.db(2)),'+r','LineWidth',2);
            % plot the symmetry point
            if length(res.db) > 2 && res.db(3) > 0
                plot(handles.axes1,res.trace1.x(res.db(3)),res.trace1.y(res.db(3)),'+m','LineWidth',2);
            end
        end
    end
end


    
grid(handles.axes1,'on');
%hold off;

% %% %
% print some results to the workspace
fprintf(1,'\n');
if isfield(res,'clock')
    fprintf(1,'      Timestamp: %s\n',datestr(res.clock));
end
if isfield(res,'mark1')
    fprintf(1,' Peak Frequency: %.3f %s',res.mark1.x,units1.x);
    if res.mark1.x > 5e5
        fprintf(1,' (%.3f MHz)\n',res.mark1.x/1e6);
    else
        fprintf(1,'\n');
    end    
    fprintf(1,' Peak Amplitude: %.3f %s',res.mark1.y,units1.y);
end
if isfield(res,'fft_max')
    fprintf(1,' Peak Frequency: %g Hz',res.fft_max);
    if res.fft_max > 5e5
        fprintf(1,' (%.3f MHz)',res.fft_max/1e6);
%     else
%         fprintf(1,'\n');
    end
end
if isfield(res,'Hn')
    fprintf(1,'    Hn: %.3f\n',res.Hn);
else
    fprintf(1,'\n');
end
if isfield(res,'Q')
    fprintf(1,'              Q: %.0f  ',res.Q);
end
if isfield(res,'bandwidth')
    fprintf(1,'\t\t3dB Bandwidth: %.0f %s\n',res.bandwidth,units1.x);
else
    fprintf(1,'\n');
end
if isfield(res,'phase_shift') && isfield(res,'meas_span')
    fprintf(1,'    Phase shift: %.1f %s',res.phase_shift,units2.y);
    fprintf(1,' (Span: %.0f %s)\n',res.meas_span,units1.x);
end

if isfield(res,'source')
    fprintf(1,'   Source Power: ');
    if isstruct(res.source) && isfield(res.source,'level')
        fprintf(1,'%g dBm\n',res.source.level);
    else
        fprintf(1,'%g dBm\n',res.source);
    end
end
if isfield(res,'V_bias') % old format
    fprintf(1,'   Bias Voltage: %.2f V\n',res.V_bias);
elseif isfield(res,'Vbias_set') % new format
    fprintf(1,'   Bias Voltage: %.2f V\n',res.Vbias_set);
end
if isfield(res,'equ_circuit') && isfield(res,'amp_gain') && isfield(res,'Q') && res.Q ~= -1
    fprintf(1,' Motional Resistance for a gain of %g:\n',res.amp_gain);
    fprintf(1,'                 %g ohms',res.equ_circuit(1));

    if isfield(res,'source')
        fprintf(1,' (');
        if isstruct(res.source) && isfield(res.source,'level')
            fprintf(1,'%g dBm',res.source.level);
        else
            fprintf(1,'%g dBm',res.source);
        end
        if isfield(res,'V_bias') % old format
            fprintf(1,' / %.1f Vb',res.V_bias);
        elseif isfield(res,'Vbias_set') % new format
            fprintf(1,' / %.1f Vb',res.Vbias_set);
        end
        fprintf(1,')\n');
    end
%    fprintf(1,'\n');
end

%res
fprintf(1,'\n');


% fprintf(1,'\n %s %s\n %s %f %s\n %s %g %s\n %s %g  %s %g %s\n %s %g %s\n %s %g ohms (%g dbm/%g Vb)\n',...
%     'Measurement Date:',rconvertdate(res.clock,'all'),...
%     'Response Peak:',res.mark1.x,res.units1.x,...
%     'Amplitude:',res.mark1.y,res.units1.y,...
%     'Q:',res.Q,'Phase shift:',res.phase_shift,res.units2.y,...
%     '3dB Bandwidth:',res.bandwidth,res.units1.x,...
%     'Motional Resistance (10k output gain):',res.equ_circuit(1),res.source,res.V_bias);


% save the handles
%guidata(hObject,handles)

return
% end showdata
% %% %


%% function: renvelope
function [upperenv lowerenv] = renvelope(data, dmax, method)
% [UPPERENV LOWERENV] = RENVELOPE(SIG, METHOD)
% Based on ENVELOPE by omid_dr@yahoo.com
%

% noise threshhold
if nargin < 2, dmax = 0.05; end
% default method for extrapolating for envelope
if nargin < 3, method = 'linear'; end

sig = data(:,min(size(data)));

% the envelope is where the signal turns over
upperind = find(diff(sign(diff(sig))) < 0) + 1; %upperind(1:5)=[];
lowerind = find(diff(sign(diff(sig))) > 0) + 1; %lowerind(1:5)=[];

% filter outliers
le=sig(lowerind);
ue=sig(upperind);

for i=2:length(ue)
    if abs(ue(i)-ue(i-1))>dmax
        ue(i)=ue(i-1);
    end
end

for i=2:length(le)
    if abs(le(i)-le(i-1))>dmax
        le(i)=le(i-1);
    end
end

if min(size(data))==1  % extrapolate to create the envelope with the same number of points as the
                       %  original data
    
    % extend envelope to length of data set
    f = 1;
    l = length(sig);
    try
        upperind = [f upperind l];
        lowerind = [f lowerind l];
    catch 
        upperind = [f; upperind; l];
        lowerind = [f; lowerind; l];
    end
    
    xi = f : l;
    upperenv = interp1(upperind, sig(upperind), xi, method, 'extrap');
    lowerenv = interp1(lowerind, sig(lowerind), xi, method, 'extrap');

elseif min(size(data))==2 % save envelope with max points only
    upperenv(:,1) = data(upperind,1);
    upperenv(:,2) = ue;
    %upperenv(:,2) = data(upperind,2);
    lowerenv(:,1) = data(lowerind,1);
    lowerenv(:,2) = le; 
    %lowerenv(:,2) = data(lowerenv,2); 
end

return


%% function: biascheck
% %% %
% % BIASCHECK attempts to determine the bias by checking the most popular
% %  bias sources. If none are connected, it returns -1
function biasv=biascheck(hObject, eventdata, handles)
% BIASCHECK
verbose=handles.verbose;
%handles.tools.biasset
if verbose >= 3, fprintf(1,'res_meas: Function BIASCHECK\n'); end

if ~strcmpi(handles.tools.biasset.instr,'none') && ~strcmpi(handles.tools.biasset.instr,'[none]') && ~strcmpi(handles.tools.biasset.instr,'(none)')
    if kpib('identify',handles.tools.biasset.gpib,0,0,0,0,0)
        try
            bias=kpib(handles.tools.biasset.instr,handles.tools.biasset.gpib,'read',handles.tools.biasset.channel,0,0,verbose);
            biasv=bias.volt;
            if verbose >= 1, fprintf(1,'res_meas: bias voltage: %g V\n',biasv); end
        catch
            biasv = 1776;
            if verbose >= 2, fprintf(1,'res_meas: bias voltage not available\n'); end
        end
        kpib('close',handles.tools.biasset.gpib,0,0,0,0,verbose);
    else
        if verbose >= 2, fprintf(1,'res_meas: bias voltage not available (ID)\n'); end
        biasv = 1776;
    end
else
    biasv = 1776;
    if verbose >= 2, fprintf(1,'res_meas: bias voltage not available\n'); end
end
return


%% function: rfixunits
% %% %
% % RFIXUNITS takes older format units fields and converts them to newer
% % format
function [res_out, units1, units2] = rfixunits(res_in)
% [RES_OUT, UNITS1, UNITS2] = RFIXUNITS(RES_IN)

res_out=res_in;
units1.x=''; units1.y='';
units2.x=''; units2.y='';
try

    if isfield(res_out,'units1')
        if ~isfield(res_out.trace1,'units')
            res_out.trace1.units=res_out.units1;
        end
        res_out=rmfield(res_out,'units1');
    end
    if isfield(res_out,'units2')
        if ~isfield(res_out.trace2,'units')
            res_out.trace2.units=res_out.units2;
        end
        res_out=rmfield(res_out,'units2');
    end

    if isfield(res_out,'trace1') && isfield(res_out.trace1,'units')
        if strcmp(res_out.trace1.units.y, 'DB')
            res_out.trace1.units.y = 'dB';
        end
        if strcmp(res_out.trace1.units.x, 's')
            res_out.trace1.units.x = 'sec';
        end        
        units1=res_out.trace1.units;
    end
    if isfield(res_out,'trace2') && isfield(res_out.trace2,'units')
        if strcmp(res_out.trace2.units.y, 'DEG') || strcmp(res_out.trace2.units.y, 'Deg')
            res_out.trace2.units.y = 'deg';
        end
        units2=res_out.trace2.units;
    end

catch
    fprintf(1,'res_meas: Warning: units not fixed.\n');
end

return

%% function: rgetfields
% %% %
% % RGETFIELDS asks the user for missing information 
function res_out = rgetfields(res_in)
% RES_OUT = RGETFIELDS(RES_IN)

res_out=res_in;

% try

% are some fields missing?
    %field_prompt={'Some values are missing from this file.'};
    %field_values={'Enter values if known, or leave blank.'};
    %field_list={'prompt'};
    num_lines=0;
    if ~isfield(res_out,'amp_gain') || ( isfield(res_out,'amp_gain') && res_out.amp_gain==0 )
        num_lines=num_lines+1;
        field_prompt(num_lines)={'Amplifier Gain'};
        field_values(num_lines)={''};
        field_list(num_lines)={'amp_gain'};
    end
    if ~isfield(res_out,'Vbias_set')
        num_lines=num_lines+1;
        field_prompt(num_lines)={'Bias Voltage (V)'};
        field_values(num_lines)={''};
        field_list(num_lines)={'Vbias_set'};
    end
    if ~isfield(res_out,'source')
        num_lines=num_lines+1;
        field_prompt(num_lines)={'Stimulus Power (dBm)'};
        field_values(num_lines)={''};
        field_list(num_lines)={'source'};
    end
    % ask if the user knows these values
    if num_lines > 0
        user_fields=inputdlg(field_prompt,'Enter Missing Values',1,field_values,'on')
        if ~isempty(user_fields)
            k=0;
            for k=1:length(field_list)
                res_out=setfield(res_out,field_list{k},str2num(user_fields{k}));
            end
        end
    end
    
% catch
%     fprintf(1,'res_meas: Warning: fields not fixed.\n');
% end

return


%% function: rconvertdate
% %% %
% % RCONVERTDATE formats the date and time for filename purposes.
% %  its the same as the standalone "convertdate.m"
function datetime = rconvertdate(date,amount)
% DATETIME = RCONVERTDATE(DATE,'AMOUNT')
%
% This function converts the Matlab date into that similar to LabView in
% order to ensure maximum compatibility.  It outputs the date and time as a
% string.
% JTL AUG2004

%Makes sure all numbers are two digits.
hour = num2str(date(4),'%02d');
min = num2str(date(5),'%02d');
day = num2str(date(3),'%02d');


%Converts the numbered month into 3 characters.
switch date(2)
    case 1
        month = 'JAN';
    case 2
        month = 'FEB';
    case 3
        month = 'MAR';
    case 4
        month = 'APR';
    case 5
        month = 'MAY';
    case 6
        month = 'JUN';
    case 7
        month = 'JUL';
    case 8
        month = 'AUG';
    case 9
        month = 'SEP';
    case 10
        month = 'OCT';
    case 11
        month = 'NOV';
    case 12
        month = 'DEC';
end

second = num2str(round(date(6)),'%02.0f');
if nargin >1
    switch amount
        case 'all'
            datetime = [day,month,num2str(date(1)),' ',hour,':',min,':',second];
        case 'day'
            datetime = [day,month,num2str(date(1))];
        case 'num'
            datetime = [num2str(date(1)),num2str(date(2),'%02d'),day,hour,min,second];
        case 'file'
            datetime = [hour,min,'_',day,month,num2str(date(1))];
        otherwise
            datetime = [day,month,num2str(date(1)),' ',hour,min];
    end
else
    datetime = [day,month,num2str(date(1)),' ',hour,min];
end

return


%% function: ridentify
% %% %
% % RIDENTIFY checks to see if the instrument is on the GPIB bus.
function instrstr = ridentify(gpibaddr)
% RETVAL = RIDENTIFY(GPIBADDR)

% send the GPIB "identify yourself" command
try
    instrstr=kpib('identify',gpibaddr,0,0,0,0,0);
    if instrstr ~= 0
        fprintf(1,'  Instrument at %d identifies itself as:\n',gpibaddr);
        fprintf(1,'    %s\n',instrstr);
        fprintf(1,'  Please verify that the Analyzer is ready to perform a measurement.\n\n');
    else
        fprintf(1,'  ERROR: No Instrument detected at GPIB %d!\n',gpibaddr);
    end
    fprintf(1,'\n');
    kpib('close',gpibaddr,0,0,0,0,0)
catch
    fprintf(1,'\n%s\n%s\n%s\n%s\n\n',...
        'res_meas: ERROR: kpib error. Verify:',...
        '          instrument is on;',...
        '          kpib.m and Instrument Control Toolbox are installed;',...
        '          GPIB interface board and driver are functional.');
    instrstr = 0;
end

return



% %% %% %% %% %
% The fields below display the results of the measurement
% no code associated with these fields

function field_peak_freq_Callback(hObject, eventdata, handles)
% hObject    handle to field_peak_freq (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 field_peak_freq as text
%        str2double(get(hObject,'String')) returns contents of field_peak_freq as a double


% function field_bandwidth_Callback(hObject, eventdata, handles)
% hObject    handle to field_bandwidth (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 field_bandwidth as text
%        str2double(get(hObject,'String')) returns contents of
%        field_bandwidth as a double


function field_peak_amp_Callback(hObject, eventdata, handles)
% hObject    handle to field_peak_amp (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 field_peak_amp as text
%        str2double(get(hObject,'String')) returns contents of field_peak_amp as a double


function field_q_Callback(hObject, eventdata, handles)
% hObject    handle to field_q (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 field_q as text
%        str2double(get(hObject,'String')) returns contents of field_q as a double


Contact us