function gui
%%
% Initialization tasks
fig = figure(1);
clf(fig,'reset');
set(fig, 'NumberTitle', 'off',...
    'Name', 'BPM RF Cal Tool',...
    'Position', [600 250 500 400], ...
    'Resize', 'off', ...
    'ToolBar', 'none',...
    'MenuBar', 'none',...
    'Visible', 'on');
PP = [];
%%
%Construct the components
hFileMenu = uimenu(... % File menu
    'Parent',fig,...
    'HandleVisibility','callback', ...
    'Label','File');
hAboutMenuitem = uimenu(... % Help menu item
    'Parent',hFileMenu,...
    'Label','About',...
    'Separator','off',...
    'HandleVisibility','callback', ...
    'Callback', @hAboutMenuItemCallback');
hCloseMenuitem = uimenu(... % Close menu item
    'Parent',hFileMenu,...
    'Label','Close',...
    'Separator','off',...
    'HandleVisibility','callback', ...
    'Callback', @hCloseMenuItemCallback');
gen_params = uipanel('parent', fig,...
    'title', 'Generator Parameters',...
    'fontsize', 15,...
    'titleposition', 'centertop',...
    'units', 'normalized',...
    'Position', [.01 .035 .45 .9],...
    'backgroundcolor', [0.8314    0.8157    0.7843]);
gen_devinfo = uipanel('Parent', gen_params,...
    'Title', 'Device Info',...
    'Units', 'normalized',...
    'position', [.01 .6 .98 .39]);
gen_ip_text = uicontrol(gen_devinfo, 'Style', 'text',...
    'String', 'IP address',...
    'Units', 'normalized', ...
    'position', [0 .75 .4 .2]);
gen_status_text = uicontrol(gen_devinfo, 'Style', 'text',...
    'String', 'Connection Status',...
    'Units', 'normalized', ...
    'position', [0 .4 .4 .3]);
gen_id_text = uicontrol(gen_devinfo, 'Style', 'text',...
    'String', 'Device Identity',...
    'Units', 'normalized', ...
    'position', [0 .1 .4 .2]);
gen_ip_in = uicontrol(gen_devinfo, 'Style', 'edit',...
    'String', 'Enter IP Address',...
    'Units', 'normalized',...
    'position', [.44 .75 .55 .2],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring', 'Enter instrument IP address in dot-decimal form');
gen_status_display = uicontrol(gen_devinfo, 'Style', 'text',...
    'String', 'Not connected',...
    'Units', 'normalized',...
    'position', [.44 .45 .55 .16],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring', 'Displays connection status of Signal Generator');
gen_id_display = uicontrol(gen_devinfo, 'Style', 'text',...
    'String', '',...
    'Units', 'normalized',...
    'position', [.44 .15 .55 .16],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring', 'Displays device information');
gen_devparams = uipanel('Parent', gen_params,...
    'Title', 'Device Parameters',...
    'Units', 'normalized',...
    'position', [.01 0 .98 .6]);
gen_freq_text = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Frequency',...
    'horizontalalignment', 'left',...
    'Units', 'normalized',...
    'position', [.01 .85 .5 .1]);
gen_freq_in = uicontrol(gen_devparams, 'Style', 'edit',...
    'String', 'Enter frequency',...
    'Units', 'normalized',...
    'position', [.51 .87 .48 .1],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring','Valid frequencies range from 9kHz to 6GHz with 0.01Hz resolution');
gen_freqbuttons = uibuttongroup('Parent', gen_devparams,...
    'Title', '',...
    'Units', 'normalized',...
    'position', [.01 .75 .98 .1 ]);
gen_button_Hz = uicontrol(gen_freqbuttons, 'Style', 'radiobutton',...
    'string', 'Hz',...
    'Units', 'normalized',...
    'position', [0 0 .25 1]);
gen_button_kHz = uicontrol(gen_freqbuttons, 'Style', 'radiobutton',...
    'string', 'kHz',...
    'Units', 'normalized',...
    'position', [.25 0 .25 1]);
gen_button_MHz = uicontrol(gen_freqbuttons, 'Style', 'radiobutton',...
    'string', 'MHz',...
    'Units', 'normalized',...
    'position', [.5 0 .25 1]);
gen_button_GHz = uicontrol(gen_freqbuttons, 'Style', 'radiobutton',...
    'string', 'GHz',...
    'Units', 'normalized',...
    'position', [.75 0 .25 1]);
gen_power = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Power settings',...
    'horizontalalignment', 'left',...
    'Units', 'normalized',...
    'position', [.01 .6 .45 .1]);
gen_power_start = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Sweep start (dBm):',...
    'horizontalalignment', 'left',...
    'units', 'normalized',...
    'position', [.03 .55 .45 .07]);
gen_power_start_in = uicontrol(gen_devparams, 'Style', 'edit',...
    'String', '',...
    'units', 'normalized',...
    'position', [.5 .55 .45 .08],...
    'backgroundcolor', [1 1 1], ...
    'tooltipstring', 'Valid range: –120 to +18 dBm');
gen_power_end = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Sweep end (dBm):',...
    'horizontalalignment', 'left',...
    'units', 'normalized',...
    'position', [.03 .4 .45 .07]);
gen_power_end_in = uicontrol(gen_devparams, 'Style', 'edit',...
    'String', '',...
    'units', 'normalized',...
    'position', [.5 .4 .45 .08],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring', 'Valid range: –120 to +18 dBm');
gen_power_step = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Sweep step size:',...
    'horizontalalignment', 'left',...
    'units', 'normalized',...
    'position', [.03 .25 .4 .07]);
gen_power_step_in = uicontrol(gen_devparams, 'Style', 'edit',...
    'String', '',...
    'units', 'normalized',...
    'position', [.5 .25 .45 .08],...
    'backgroundcolor', [1 1 1], ...
    'tooltipstring', 'Assure that range setting are acceptable to avoid error');
gen_power_time = uicontrol(gen_devparams, 'Style', 'text',...
    'String', 'Sweep step time:',...
    'horizontalalignment', 'left',...
    'units', 'normalized',...
    'position', [.03 .1 .4 .07]);
gen_power_time_in = uicontrol(gen_devparams, 'Style', 'edit',...
    'String', '',...
    'units', 'normalized',...
    'position', [.5 .1 .45 .08],...
    'backgroundcolor', [1 1 1]);
bpm_params = uipanel('parent', fig,...
    'Title', 'BPM Parameters',...
    'Fontsize', 15,...
    'units', 'normalized',...
    'position', [.54 .585 .45 .35],...
    'titleposition', 'centertop');
bpm_ip_text = uicontrol(bpm_params, 'style', 'text',...
    'string', 'IP address',...
    'units', 'normalized',...
    'position', [.01 .85 .4 .1]);
bpm_port_text = uicontrol(bpm_params, 'style', 'text',...
    'string', 'Port #',...
    'units', 'normalized',...
    'position', [.01 .65 .4 .1]);
bpm_ref_text = uicontrol(bpm_params, 'style', 'text',...
    'string', 'Reference addr',...
    'units', 'normalized',...
    'position', [.01 .45 .4 .1]);
bpm_numregs_text = uicontrol(bpm_params, 'style', 'text',...
    'string', 'Number of registers to read',...
    'units', 'normalized',...
    'position', [.01 .10 .4 .25]);
bpm_ip_in = uicontrol(bpm_params, 'style', 'edit',...
    'string', 'IP address',...
    'units', 'normalized',...
    'position', [.5 .825 .4 .125],...
    'backgroundcolor', [1 1 1], ...
    'tooltipstring', 'Enter BPM IP address in dot-decimal format');
bpm_port_in = uicontrol(bpm_params, 'style', 'edit',...
    'string', '502',...
    'units', 'normalized',...
    'position', [.5 .625 .4 .125],...
    'backgroundcolor', [1 1 1], ...
    'tooltipstring', 'Default port value is 502 for ModBus-TCP');
bpm_ref_in = uicontrol(bpm_params, 'style', 'edit',...
    'string', 'Ref addr',...
    'units', 'normalized',...
    'position', [.5 .425 .4 .125],...
    'backgroundcolor', [1 1 1], ...
    'tooltipstring', 'Reference index for first register to be read');
bpm_numregs_in = uicontrol(bpm_params, 'style', 'edit',...
    'string', '# Regs',...
    'units', 'normalized',...
    'position', [.5 .2 .4 .125],...
    'backgroundcolor', [1 1 1],...
    'tooltipstring', 'Number of registers to read');
control_params = uipanel('parent', fig,...
    'Title', 'Control',...
    'fontsize', 15,...
    'titleposition', 'centertop',...
    'units', 'normalized',...
    'position', [.54 .035 .45 .35]);
control_runsweep = uicontrol(control_params, 'Style', 'pushbutton',...
    'string', 'Run Sweep',...
    'units', 'normalized',...
    'position', [.01 .75 .98 .25], ...
    'tooltipstring', ['Runs a sweep from and collects RSSI data for specified power range' ...
    ' using the specified step size. Stored data is deleted upon Post Processing']);
control_readregs = uicontrol(control_params, 'Style', 'pushbutton',...
    'string', 'Read Registers',...
    'units', 'normalized',...
    'position', [.01 .425 .98 .25], ...
    'tooltipstring', 'Collects one set of RSSI data for power level specified by "Sweep start"');
control_process = uicontrol(control_params, 'Style', 'pushbutton',...
    'string', 'Post Process',...
    'units', 'normalized',...
    'position', [.01 .10 .98 .25], ...
    'TooltipString', ['Calculates Systematic Gain Coefficients from collected RSSI data. Output is' ...
    ' saved to a file and current RSSI data is discarded']);
haxis = axes('Parent', fig, ...
    'Position', [.48 .39 .57 .19]);
imshow('image.jpg');
hTitle = uicontrol('Parent', fig, 'Style', 'text',...
    'String', 'NSLS-II Intrumentation and Diagnostics Group: RF BPM CalTool',...
    'Fontweight', 'bold',...
    'Fontsize', 12,...
    'Backgroundcolor' , [0.8 0.8 0.8],...
    'Units', 'normalized',...
    'Position', [0 .95 1 .05]);
hVersion = uicontrol('Parent', fig, 'style', 'text',...
    'string', 'Property of Brookhaven National Laboratory, version 1.0',...
    'backgroundcolor', [0.8 0.8 0.8],...
    'fontsize', 8,...
    'horizontalalignment', 'center',...
    'units', 'normalized',...
    'position', [0 0 1 .03]);
%%
% Initialization tasks
freq_mult = ' Hz';  %frequency multiplier based off radio buttons
gen_ip = '';
freq = '';
sweep_start = '';
sweep_end = '';
sweep_step = 0;
sweep_time = 0;
bpm_ip = '';
bpm_port = '';
bpm_ref = 0;
bpm_numregs = 0;
%%
% Callbacks for MYGUI
%set(gen_ip_in, 'buttondownfcn','if(get(gen_ip_in,''String'') == ''Enter IP Address'') set(gen_ip_in,''String'',''dfgdfg''); end');
set(gen_button_Hz, 'callback', 'freq_mult = '' Hz'';');
set(gen_button_kHz, 'callback', 'freq_mult = '' kHz'';');
set(gen_button_MHz, 'callback', 'freq_mult = '' MHz'';');
set(gen_button_GHz, 'callback', 'freq_mult = '' GHz'';');
set(control_process, 'callback', @postprocess);
set(control_runsweep, 'callback', @runsweep);
set(control_readregs, 'callback', @regread);
%%
% Utility functions for MYGUI
    function runsweep(hObjet,eventdata)
        
        %call function and read inputs
        ReadInputs
        %create tcpip objects and set params
        gen_ip = ['TCPIP::' gen_ip '::instr0::INSTR']
        gen = visa('ni', gen_ip)
        bpm = tcpip(bpm_ip,bpm_port);
        set(bpm, 'InputBufferSize', 10000);
        %connect to tcp objects
        fopen(gen); %open connection to SG
        fopen(bpm);     %open connection to BPM
        set(gen_status_display,'String', 'Connected');
        set(gen_status_display,'backgroundcolor', [0 1 0]);
        fprintf(gen, '%c', '&GTR');    %set SG to remote control mode
        identity = query(gen, '*idn?');    %query identity
        set(gen_status_display, 'String', identity);    %change text in gui
        fprintf(gen, '%c', '*rst');    %reset SG
        %loop:
        gen_freq = [':SOURce:FREQuency:CW ' freq freq_mult]
        fprintf(gen, '%c', gen_freq);    %set to CW mode and freq
        start = str2num(sweep_start);
        finish = str2num(sweep_end);
        for i = start:sweep_step:finish
            %set freq generator
            p_set = [':source:power ' num2str(i)]
            fprinff(gen, '%c', p_set);   %set output power to -20 dBm
            fprintf(gen, '%c', ':output:state ON');    %turn on rf out
            pause(1);
            %read value from bpm
            read = MB_RegRead(bpm,bpm_ref,bpm_numregs)
            PP = [PP; i read]    %post processing variable
        end
        %format and store read values in output
        %close connections
        fprintf(gen, '%c', ':output:state OFF');    %turn off rf output
        fprintf(gen, '%c', '&GTL');    %set SG to local mode
        fclose(gen);   %disconnect
        fclose(bpm);
        set(gen_status_display,'String', 'Disconnected');
        set(gen_status_display,'backgroundcolor', [1 1 1]);
    end

    function regread(hObject,eventdata)
        %call function and read inputs
        ReadInputs
        %create tcpip objects
        gen_ip = ['TCPIP::' gen_ip '::instr0::INSTR'];
        gen = visa('ni', gen_ip);
        bpm = tcpip(bpm_ip,bpm_port);
        set(bpm, 'InputBufferSize', 10000);
        %connect to tcpip objects
        fopen(gen); %open connection to SG
        fopen(bpm);     %open connection to BPM
        set(gen_status_display,'String', 'Connected');
        set(gen_status_display,'backgroundcolor', [0 1 0]);
        fprintf(gen, '%c', '&GTR');    %set SG to remote control mode
        identity = query(gen, '*idn?');    %query identity
        set(gen_status_display, 'String', identity);    %change text in gui
        fprintf(gen, '%c', '*rst');    %reset SG
        %set function generator
        gen_freq = [':SOURce:FREQuency:CW ' freq freq_mult]
        fprintf(gen, '%c', gen_freq);    %set to CW mode and freq to 0.5 GHz
        p_set = [':source:power ' sweep_start]
        fprinff(gen, '%c', p_set);   %set output power to -20 dBm
        fprintf(gen, '%c', ':output:state ON');    %turn on rf output
        %read registers
        read = MB_RegRead(bpm,bpm_ref,bpm_numregs)
        PP = [PP; str2num(sweep_start) read]    %post processing variable
        %close connections
        fprintf(gen, '%c', ':output:state OFF');    %turn off rf output
        fprintf(gen, '%c', '&GTL');    %set SG to local mode
        fclose(gen);   %disconnect
        fclose(bpm);
        set(gen_status_display,'String', 'Disconnected');
        set(gen_status_display,'backgroundcolor', [1 1 1]);
    end

    function postprocess(hObject,eventdata)
        %User prompt
        selection = questdlg(['All data collected before post-processing will'...
            ' be saved and discarded for new collection. Continue?'],...
            'Post Process?', 'Yes', 'No', 'Yes');
        if strcmp(selection, 'No')
            return;
        end
        %User selected yes, so calculate gain coeffs
        output = PP;
        [rows cols] = size(output);
        for i=1:rows
            temp = output(i,2);
            for k = 2:cols
                output(i,k) = output(i,k)/temp; %normalize values
            end
        end
        %Obtain file name and path for saving output
        [filename, pathname, filterindex] = uiputfile( ...  %obtain filename and path
            {'*.dat','DAT-files (*.dat)'; ...               %for saving file
            '*.txt','Text (*.txt)'; ...
            '*.*',  'All Files (*.*)'}, ...
            'Save output as', 'Output.dat');
        %create/open file for writing
        file = fopen([pathname filename],'w');
        %get system date and time for header
        c = clock;
        %write file header to file
        fprintf(file,'$HEAD DATA COEFF %d-%d-%d %d:%d:%d:00 -- Head description\n',c(2),c(3),c(1),c(4),c(5),c(6));
        %write output values (gain coeffs) to file, line by line
        for i=1:rows
            temp_str = [];   %temporary string for current line of output
            for k=1:cols
                temp_str = [temp_str num2str(output(i,k)) ','];
            end
            fprintf(file,'%s\n',temp_str);
            %output_str = [output_str;temp_str];  %store concatenated values
        end
        %close file after data writing is complete
        fclose(file);
        %rest PP for next series of data
        PP = [];
    end

    function ReadInputs
        gen_ip = get(gen_ip_in,'String');
        freq = get(gen_freq_in, 'String');
        sweep_start = get(gen_power_start_in, 'String');
        sweep_end = get(gen_power_end_in, 'String');
        sweep_step = str2num(get(gen_power_step_in, 'String'));
        %             if (isempty(sweep_step))
        %                 sprintf('Invalid entry for step time. \nPlease correct and',...
        %                     ' try again\n');
        %                 return
        %             elseif (isnan(sweep_step))
        %                 sprintf('Invalid entry for step time. \nPlease correct and',...
        %                     ' try again\n');
        %                 return
        %             end
        sweep_time = str2num(get(gen_power_time_in, 'String'));
        bpm_ip = get(bpm_ip_in,'String');
        bpm_port = str2num(get(bpm_port_in,'String'));
        bpm_ref = str2num(get(bpm_ref_in,'String'));
        bpm_numregs = str2num(get(bpm_numregs_in,'String'))
    end

    function bpm_result = MB_RegRead(bpm_obj,reference,num_regs)
        %This function queues the ModBus device
        %and reads num_regs output registers
        %starting from reference
        
        %Create fields of request
        trans_id = [0 0];
        protoc_id = [0 0];
        lnth_upper = [0];
        lnth_lower = [6];   %does not need to be adjusted - constant for FC=3
        lnth = [lnth_upper lnth_lower];
        unit_id = [1];
        fc = [3];
        ref = [floor(reference/256) mod(reference,256)];
        word_cnt = [floor(num_regs/256) mod(num_regs,256)];
        %Create request
        request = [trans_id protoc_id lnth unit_id fc ref word_cnt];
        %Talk to provided bpm tcpip object
        %Send request, wait, process response
        fwrite(bpm_obj, request, 'uint8');
        %sprintf('\nPausing...\n');
        pause(1);
        %sprintf('\nReading...\n');
        bytes_rcvd = get(bpm_obj, 'BytesAvailable')
        if (bytes_rcvd < (8+1+(2*num_regs)))
            errordlg('Error with number of bytes received. Check to make sure response UID/FC/Length fields match',...
                'Byte read error');
            return
        else
            raw_response = fread(bpm_obj,bytes_rcvd,'uint8');
            response_hdr = raw_response(1:7);
            response_PDU = raw_response(8:bytes_rcvd)';   %strip header
        end
        bpm_result = zeros(1,num_regs);
        k = 1;
        for i=3:2:length(response_PDU)
            bpm_result(k) = response_PDU(i)*256 + response_PDU(i+1);
            k = k+1;
        end
        bpm_result
    end

%Callback for when the "Close" menu option is selected
    function hCloseMenuItemCallback(hObject, eventdata)
        selection = questdlg('Would you like to exit? (any unsaved data will be lost)',...
            'Exit program?', 'Yes', 'No', 'Yes');
        if strcmp(selection, 'No')
            return;
        end
        delete(fig);
    end

%Callback for when the "Help" menu option is selected
    function hAboutMenuItemCallback(hObject, eventdata)
        out = msgbox(['About the RF BPM CalTool: This tool was developed by Samuel Fanfan' ...
            ' for the purposes stated by Brookhaven National Laboratory. All rights reserved']...
            , 'About', 'modal');
    end
end