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