% ADS and Network Analyzer Data Plotting Utility
%
% User Interface and Callbacks: Rod Draney
%
% To do:
%	Add Path Support
%
% Network Analyzer Functions (fdata.m, hp8510c.m) Author: Nilesh Kamdar
%
% Send bugs to slj9r@cc.usu.edu


function varargout = gui(varargin)
% gui Application M-file for gui.fig
%    FIG = gui launch gui gui.
%    gui('callback_name', ...) invoke the named callback.

% Last Modified by guiDE v2.0 02-Apr-2001 16:55:12

if nargin == 0  % LAUNCH gui

	fig = openfig(mfilename,'reuse');
	% Generate a structure of handles to pass to callbacks, and store it. 
	handles = guihandles(fig);
	guidata(fig, handles);
    Data_struct.ADS_flag=0;     % Initialization
    Data_struct.NA_flag=0;
    set(fig,'UserData',Data_struct);

	if nargout > 0
		varargout{1} = fig;
	end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

	try
		[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
	catch
		disp(lasterr);
	end

end


%| ABOUT CALLBACKS:
%| guiDE automatically appends subfunction prototypes to this file, and 
%| sets objects' callback properties to call them through the FEVAL 
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the 
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in gui using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at gui startup using guiHANDLES and stored in
%| the figure's application data using guiDATA. A copy of the structure
%| is passed to each callback.  You can store additional information in
%| this structure at gui startup, and you can change the structure
%| during callbacks.  Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, guiDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.



% --------------------------------------------------------------------
function varargout = listbox1_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.listbox1.

% --------------------------------------------------------------------
function varargout = listbox2_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.listbox1.



% --------------------------------------------------------------------
function varargout = edit1_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.edit1.

handles.pushbutton1.String='Hello';

fig=guidata(gcbo);
filename=get(fig.edit1,'String');

edit1_change(filename);
return;

% --------------------------------------------------------------------
function varargout = edit2_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.edit2.

fig=guidata(gcbo);
filename=get(fig.edit2,'String');

edit2_change(filename);
return;

% --------------------------------------------------------------------
function varargout = pushbutton2_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.pushbutton2.
fig=guidata(gcbo);
n1=get(fig.listbox1,'Value');
n2=get(fig.listbox2,'Value');
Data=get(fig.figure1,'UserData');
check1=get(fig.checkbox1,'Value');
check2=get(fig.checkbox2,'Value');
check=check1&check2;

if check == 0
    if check1 == 1
        plot(Data.ADS_f,Data.ADS_data(n1).data,'--');
    elseif check2 == 1
        plot(Data.NA_f,Data.NA_data(n2).data);
    end
else
    if Data.ADS_flag == 1
        plot(Data.ADS_f,Data.ADS_data(n1).data,'--');
        if Data.NA_flag == 1
            hold on;
            plot(Data.NA_f,Data.NA_data(n2).data);
        end
    elseif Data.NA_flag == 1
        plot(Data.NA_f,Data.NA_data(n2).data);
        if Data.ADS_flag == 1
            hold on;
            plot(Data.ADS_f,Data.ADS_data(n1).data,'--');
        end
    end
end




% Determine number of data blocks in ADS file
function [titles,block_count]=ADSBlocks(fid);
a=1;
block_count=0;
titles='';
while feof(fid) ~= 1
    a=fgetl(fid);
    if length(a) > 3
        if a(1:4)=='freq'
            block_count=block_count+1;
            titles=strvcat(titles,a(6:length(a)));            
        end
    end
end
return;

% Determine number of data elements in ADS block
function num_data=ADSDatacount(fid)
a=1;
count=0;
while length(a) ~= 0
    a=fgetl(fid);
    count=count+1;
end

num_data=count-2;
return;

% Read data from ADS file
function [data_struct,f]=ADSGetdata(fid,num_data,block_count)

% Setup struct
i=[1:1:num_data];    
for j=1:block_count
    title=sprintf('ADS_%d',j);
    name=fgetl(fid);        % Read text line
    data=fscanf(fid,'%f',2*num_data);
    a=fgetl(fid);           % Read blank lines to move file pointer to next block
    a=fgetl(fid);           % "
    a=fgetl(fid);           % "
    x=data(2.*i-1);
    y=data(2.*i);
    data_struct(j).data=y;
end
f=x;
return;

function [S11, S21, S12, S22, freq] = hp8510c(fname)
% Author : Nilesh Kamdar
% This function will take in a file as the parameter
% and give five outputs. S11, S22, S12, S21 and frequency.
% Each S parameter returned is an array with imaginary
% elements i.e S11real + j*S11imag. The function
% strips off the network analyzer header and returns
% the S-params and the frequency sweep for the readings

% open the file
fid = fopen(fname);

% check if file exists in directory.
% Note: for function to work, both the function file
% and the network analyzer output file have to be in 
% same directory.
if (fid == -1)
   disp('Invalid File name');
   break;
end

% initialize a few variables
flag1 = 0;
k = 1;
count = 0;

% start endless loop of reading file
while 1
   % read one line at a time as string
  	line = fgetl(fid);
     
   % when last line break out of while loop
   if ~isstr(line)
     	break;
   end
   %disp(line)
   
   warning off;
   
   % search for the line with frequency parameters
   % this line starts with SEG 
   if (findstr(line, 'SEG ') == 1)
      [word, remain] = strtok(line); % This removes the word SEG
      [f1, remain] = strtok(remain); % This removes the start frequency
      [f2, totpts] = strtok(remain); % This removes the stop frequency and total no of pts
      f1 = eval(f1);  % convert string to numeric
      f2 = eval(f2);  % convert string to numeric
      totpts = eval(totpts);  % convert string to numeric
      step = (f2 - f1)/(totpts - 1);  %calculate the step increment
      freq = f1:step:f2;  % set up the frequency sweep variable
      
   % search for BEGIN which means s params start at next line
   elseif (findstr(line, 'BEGIN') == 1)  
      flag1 = 1;
      count = count + 1; % this will indicate if the params are s11 or s12 or s21 or s22
      
   % search for END which means s params ended.
   % now put collected s params in suitable variables
   elseif (findstr(line, 'END') == 1)
      flag1 = 0;
      k = 1;
      switch (count)
      	case 1, S11 = Sreal + i.*Simag;
      	case 2, S21 = Sreal + i.*Simag;
      	case 3, S12 = Sreal + i.*Simag;
      	case 4, S22 = Sreal + i.*Simag;
      end
      
   % enters this part only if begin has been found and no end has been found
   % Thus this line contains the sparam itself   
   elseif (flag1 == 1)
      % parsing using delimiter ','
      [part1, part2] = strtok(line, ','); % gets S11 real
      [part2, part3] = strtok(part2, ','); % gets S11 imag
      Sreal(k) = eval(part1);  % convert string to numeric
      Simag(k) = eval(part2);  % convert string to numeric
      k = k + 1;
   end

   warning on;
end
fclose(fid); % close the file

function [logmag, vswr, phaseang] = fdata(Sii)
% Author: Nilesh Kamdar
% This file will format the data obtained from the hp8510c function
% Its inputs are the Sparams and output is data in the foll formats:
% Log mag, VSWR, Phase

% this gets the log mag part
absSii = abs(Sii);
logmag = 10*log10(absSii);

% this gets the VSWR data
vswr = (1 + absSii)./(1 - absSii);

% This gets phase plots
temp1 = atan(imag(Sii)./real(Sii));
phaseang = temp1/pi*180;

% more formats can be added to this function


% --------------------------------------------------------------------
function varargout = pushbutton3_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.pushbutton3.
%disp('pushbutton3 Callback not implemented yet.')
fig=guidata(gcbo);
temp_data=get(fig.listbox1,'String');
set(fig.listbox1,'String','');
filename=uigetfile;
if filename ~= 0
    set(fig.edit1,'String',filename);
    edit1_change(filename);
else
    set(fig.listbox1,'String',temp_data);
end


% --------------------------------------------------------------------
function varargout = pushbutton4_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.pushbutton4.
%disp('pushbutton4 Callback not implemented yet.')
fig=guidata(gcbo);
temp_data=get(fig.listbox2,'String');
set(fig.listbox2,'String','');
filename=uigetfile;
if filename ~= 0
    set(fig.edit2,'String',filename);
    edit2_change(filename);
else
    set(fig.listbox2,'String',temp_data);
end

% --------------------------------------------------------------------
function edit1_change(filename)

fig=guidata(gcbo);

set(fig.listbox1,'String','Please Wait.  Loading Data ...');
drawnow;

fid=fopen(filename);
if fid < 0
    set(fig.listbox1,'String','');
    Data_struct=get(fig.figure1,'UserData');
    Data_struct.ADS_flag=0;
    set(fig.figure1,'UserData',Data_struct);
    
    msgbox('Invalid or nonexistent file.', 'Error');
    
else
    fclose(fid);            % Close and reopen file to point to beginning
    fid=fopen(filename);
    
    % Determine number of and titles of data blocks
    [titles,block_count]=ADSBlocks(fid);
    set(fig.listbox1,'String',titles);

    % Determine number of actual data elements in single array
    fclose(fid);            % Close and reopen file to point to beginning
    fid=fopen(filename);
    num_data=ADSDatacount(fid);
    
    % Read in each data set
    fclose(fid);            % Close and reopen file to point to beginning
    fid=fopen(filename);
    Data_struct=get(fig.figure1,'UserData');
    [Data_struct.ADS_data,Data_struct.ADS_f]=ADSGetdata(fid,num_data,block_count);

    Data_struct.ADS_flag=1;
    set(fig.figure1,'UserData',Data_struct);
    
    fclose(fid);
end

% --------------------------------------------------------------------
function edit2_change(filename)

fig=guidata(gcbo);

set(fig.listbox2,'String','Please Wait. Loading Data ...');
drawnow;


fid=fopen(filename);
if fid < 0
    set(fig.listbox2,'String','');
    Data_struct=get(fig.figure1,'UserData');
    Data_struct.NA_flag=0;
    set(fig.figure1,'UserData',Data_struct);
    
    msgbox('Invalid or nonexistent file.','Error');
else
    
    [S11, S21, S12, S22, f] = hp8510c(filename);  % Put your filename here
    [ldata(1).data, vdata, pdata] = fdata(S11); % to see S12, S21, S22, etc. change this line here
    [ldata(2).data, vdata, pdata] = fdata(S12); % to see S12, S21, S22, etc. change this line here
    [ldata(3).data, vdata, pdata] = fdata(S21); % to see S12, S21, S22, etc. change this line here
    [ldata(4).data, vdata, pdata] = fdata(S22); % to see S12, S21, S22, etc. change this line here
    
    titles=strvcat('S11','S12','S21','S22');
    set(fig.listbox2,'String',titles);

    Data_struct=get(fig.figure1,'UserData');

    Data_struct.NA_data=ldata;
    Data_struct.NA_f=f;
    Data_struct.NA_flag=1;
        
    set(fig.figure1,'UserData',Data_struct);
end   



% --------------------------------------------------------------------
function varargout = checkbox1_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.checkbox1.
%disp('checkbox1 Callback not implemented yet.')


% --------------------------------------------------------------------
function varargout = checkbox2_Callback(h, eventdata, handles, varargin)
% Stub for Callback of the uicontrol handles.checkbox2.
%disp('checkbox2 Callback not implemented yet.')