%PlotVIPR Ver 1.0 Richard.N.Grubb with valuable assistance from Preeti Bhaneja
% To execute within MATLAB run PlotVIPR.m

% This script first selects the RIQ file to process, maps the SCT
% structure, and checks for the "magic" number in the file.

[File_Name, PathName] = uigetfile('*.RIQ','VIPR data file open');
Full_Name = strcat(PathName, File_Name);

% memmapfile enables the data structures within the file to be represented
% and mapped to MATLAB arrays. To be a valid array all entries must have the 
% same number of colunms. The file data is mapped onto the data structure in byte
% order and is then readable as the types defined below in dot notation
% e.g. SCT.data.magic The file is only accessed when data is referenced.
% The array does not exist in memory.

SCT = memmapfile (Full_Name, 'Offset', 0, 'Repeat', 1, 'Format', {    
        % System configuration table
        'int32' [1 1]  'magic'              ;    % magic number 0x51495200 (/nullRIQ) {POSSIBLY BYTE REVERSED}
        'int32' [1 1] 'sounding_table_size' ;    % bytes in sounder configuration structure (this file)
        'int32' [1 1] 'pulse_table_size'    ;    % bytes in pulse configuration structure
        'int32' [1 1] 'raw_data_size'       ;    % bytes in raw data block (one PRI) 
        'single' [1 1] 'struct_version'     ;    % Format Version Number.  Currently 1.2
        'int32' [1 1] 'start_year'          ;    % Start Time Elements of the ionogram (Universal Time)
        'int32' [1 1] 'start_daynumber'     ;    % 
        'int32' [1 1] 'start_month'         ;    % 
        'int32' [1 1] 'start_day'           ;    % 
        'int32' [1 1] 'start_hour'          ;    %
        'int32' [1 1] 'start_minute'        ;    %
        'int32' [1 1] 'start_second'        ;    %
        'int32' [1 1] 'start_epoch'         ;    % epoch time of the measurement start.
        'uint8' [4 32] 'readme'             ;    % Operator comment on this measurement
        'int32' [1 1] 'decimation_method'   ;    % If processed, 0 = no process (raw data)
        'single' [1 1] 'decimation_threshold';   % If processed, the treshold value for the given method
        'uint8' [4 32] 'user'               ;    % user-defined
        });   % Format and object end. Length 316 bytes

Station = memmapfile (Full_Name, 'Offset', 316, 'Repeat', 1, 'Format', {  
        % This contains information about the station of observation.
        % Relatively static.
        'uint8' [4 16]  'file_id'     ;   % name of station settings file
        'uint8' [4 2]   'ursi_id'     ;   % URSI standard station ID code
        'uint8' [4 8]   'rx_name'     ;   % Receiver Station Name
        'single' [1 1]  'rx_latitude' ;   % Position of the Receive array reference point [degrees North]
        'single' [1 1]  'rx_longitude';   %                                               [degrees East]
        'single' [1 1]  'rx_altitude' ;   % meters above mean sea level
        'int32' [1 1]   'rx_count'    ;   % Number of defined receive antennas
        'uint8' [4 256]   'rx_antenna_type';   % Rx antenna type text descriptors 
        'single' [1 96] 'rx_position' ;   % X,Y,Z = (East,North,Up) Positon [m] of each Rx
        'single' [1 96] 'rx_direction';   % X,Y,Z = (East,North,Up) Direction of each Rx 
        'single' [1 32] 'rx_height'   ;   % Height above ground [m]
        'single' [1 32] 'rx_cable_length'; % physical length of receive cables [m]
        'single' [1 1]  'frontend_atten'; % Front End attenuator setting
        'uint8' [4 8]  'tx_name'      ;   % Transmitter Station Name
        'single' [1 1] 'tx_latitude'  ;   % Position of the Transmit Antenna reference point [degrees North]
        'single' [1 1] 'tx_longitude' ;   %                                                  [degrees East]
        'single' [1 1] 'tx_altitude'  ;   % meters above mean sea level
        'uint8' [4 8]  'tx_antenna_type'; % Tx antenna type text descriptors 
        'single' [1 3] 'tx_vector'    ;   % tx antenna direction vector [m]
        'single' [1 1] 'tx_height'    ;   % antenna height above reference ground [m]
        'single' [1 1] 'tx_cable_length'; % physical length of transmit cables [m]
        'int32' [1 1] 'drive_band_count'; % Number of antenna drive bands
        'single' [1 128] 'drive_band_bounds'; % drive bands start/stop in kHz
        'single' [1 64] 'drive_band_atten';   % antenna drive atteunuation in dB
        'int32' [1 1] 'rf_control'    ;   % -1 = none, 0 = drive/quiet, 1 = full, 2 = only quiet, 3 = only atten
        'uint8' [4 8] 'ref_type'      ;   % Type of reference oscillator
        'uint8' [4 8] 'clock_type'    ;   % Source of absolute UT timing
        'uint8' [4 32] 'user'         ;   % Spare space for user-defined information    
     });   % Format and object end. Size 3236 bytes.
 
 Timing = memmapfile (Full_Name, 'Offset', 3552, 'Repeat', 1, 'Format', {  
        % Timing of the measurement
        'uint8' [4 16] 'file_id'           ;   % Name of the timing settings file
        'single' [1 1] 'pri'               ;   % Pulse Repetition Interval (PRI) (microseconds) 
        'int32' [1 1]  'pri_count'         ;   % number of PRI's in the measurement
        'int32' [1 1]  'ionogram_count'    ;   % repeat count for ionogram within same data file
        'single' [1 1] 'holdoff'           ;   % time between GPS 1 pps and start
        'single' [1 1] 'range_gate_offset' ;   % true range to gate 0
        'int32' [1 1]  'gate_count'        ;   % Number of range gates, adjusted up for USB blocks
        'single' [1 1] 'gate_start'        ;   % start gate placement [us], adjusted
        'single' [1 1] 'gate_end'          ;   % end gate placement [us], adjusted
        'single' [1 1] 'gate_step'         ;   % range delta [us]
        'single' [1 1] 'data_start'        ;   % data range placement start [us]
        'single' [1 1] 'data_width'        ;   % data pulse baud width [us]
        'int32' [1 1]  'data_baud_count'   ;   % data pulse baud count
        'uint8' [4 16] 'data_wave_file'    ;   % data baud pattern file name
        'single' [1 2048] 'data_baud'      ;   % data waveform baud pattern
        'int32' [1 1]  'data_pairs'        ;   % number of IQ pairs in waveform memory
        'single' [1 1]  'cal_start'        ;   % cal range placement start [us]
        'single' [1 1]  'cal_width'        ;   % cal pulse baud width [us]
        'int32' [1 1]   'cal_baud_count'   ;   % cal pulse baud count
        'uint8' [4 16]  'cal_wave_file'    ;   % alternative baud pattern file name
        'single' [1 2048] 'cal_baud'       ;   % cal waveform baud pattern
        'int32' [1 1]   'cal_pairs'        ;   % number of IQ pairs in waveform memory
        'uint8' [4 32]  'user'             ;   % Spare space for user-defined information    
  });      % Format and object end. Size 16772 bytes.

 Frequency = memmapfile (Full_Name, 'Offset', 20324, 'Repeat', 1, 'Format', {  
        % Frequency information about the measurement
        'uint8' [4 16]   'file_id'       ;  % Frequency settings file
        'single' [1 1]   'base_start'    ;  % Initial base frequency
        'single' [1 1]   'base_end'      ;  % Final base frequency
        'int32' [1 1]    'base_steps'    ;  % Number of base frequencies
        'int32' [1 1]    'tune_type'     ;  % Tuning type flag:  1=log, 2=linear, 3=table, 4=Log+Fixed ShuffleMode 
        'single' [1 8182] 'base_table'   ;  % Nominal or Base frequency table
        'single' [1 1]   'linear_step'   ;  % Linear frequency step [kHz]
        'single' [1 1]   'log_step'      ;  % Log frequency step, [percent]
        'uint8' [4 16]   'freq_table_id' ;  % Manual tuning table filename
        'int32' [1 1]    'tune_steps'    ;  % all frequencies pre-ramp repeats
        'int32' [1 1]    'pulse_count'   ;  % pulset frequency vector length		
        'int32'  [1 256] 'pulse_pattern' ;  % pulset frequency vector	
        'single' [1 1]   'pulse_offset'  ;  % pulset offset [kHz] 		
        'int32' [1 1]    'ramp_steps'    ;  % pulsets per B-mode ramp (ramp length, base freqs per B-block)		
        'int32' [1 1]    'ramp_repeats'  ;  % repeat count of B-mode ramps
        'single' [1 8192] 'drive_table'  ;  % base frequencies attenuation/silent table
        'uint8' [4 32]   'user'          ;  % Spare space for user-defined information    
 });      % Format and object end. Size 66860 bytes.

Receiver = memmapfile (Full_Name, 'Offset', 87184, 'Repeat', 1, 'Format', {  
        % Receiver settings
        'uint8'  [4 16] 'file_id'       ;  % Frequency settings file
        'int32' [1 1]   'rx_chan'       ;  % Number of receivers
        'int32' [1 16]  'rx_map'        ;  % receiver-to-antenna mapping			
        'int32' [1 1]   'word_format'   ;  % 0 = big endian fixed, 1 = little endian, 2 = floating_point
        'int32' [1 1]   'cic2_dec'      ;  % DDC filter block
        'int32' [1 1]   'cic2_interp'   ;  % DDC filter block
        'int32' [1 1]   'cic2_scale'    ;  % DDC filter block
        'int32' [1 1]   'cic5_dec'      ;  % DDC filter block
        'int32' [1 1]   'cic5_scale'    ;  % DDC filter block
        'uint8' [4 8]   'rcf_type'      ;  % text descriptor of FIR filter block  
        'int32' [1 1]   'rcf_dec'       ;  % decimation factor for FIR filter block 
        'int32' [1 1]   'rcf_taps'      ;  % number of taps in FIR filter block  
        'int32' [1 160] 'coefficients'  ;  % Receiver filter coefficients
        'single' [1 1]  'analog_delay'  ;  % analog delay of receiver, us
        'uint8' [4 32]  'user'          ;  % Spare space for user-defined information    
});      % Format and object end. Size 968 bytes.

Exciter = memmapfile (Full_Name, 'Offset', 88152, 'Repeat', 1, 'Format', {  
        % Exciter settings
        'uint8' [4 16]  'file_id'          ;  % Frequency settings file
        'int32' [1 1]   'cic_scale'        ;  % DUC filter block
        'int32' [1 1]   'cic2_dec'         ;  % DUC filter block
        'int32' [1 1]   'cic2_interp'      ;  % DUC filter block
        'int32' [1 1]   'cic5_interp'      ;  % DUC filter block
        'uint8' [4 8]   'rcf_type'         ;  % text descriptor of FIR filter block  
        'int32' [1 1]   'rcf_taps'         ;  % number of taps in FIR filter block
        'int32' [1 1]   'rcf_taps_phase'   ;  % number of taps in FIR filter block
        'int32' [1 256] 'coefficients'     ;  % Receiver? filter coefficients
        'single' [1 1]  'analog_delay'     ;  % analog delay of exciter/transmitter, us
        'uint8' [4 32]  'user'             ;  % Spare space for user-defined information    
});      % Format and object end. Size 1276 bytes.

Monitor = memmapfile (Full_Name, 'Offset', 89428, 'Repeat', 1, 'Format', {  
        % System status and Built-In-Test info
        'int32' [1 8]   'balun_currents'  ;  % As read prior to ionogram 
        'int32' [1 8]   'balun_status'    ;  % As read prior to ionogram 
        'int32' [1 8]   'front_end_status';  % As read prior to ionogram
        'int32' [1 8]   'receiver_status' ;  % As read prior to ionogram
        'int32' [1 2]   'exciter_status'  ;  % As read prior to ionogram
        'uint8' [4 128] 'user'            ;  % Spare space for user-defined information    
});      % Format and object end. Size 648 bytes

try
if SCT.data.magic ~= 1363759616 
    h = msgbox('The file is not a valid VIPR RIQ file. Please select another.','VIPR Ionogram Display','modal');
    uiwait(h)
    error('The file is not a valid VIPR RIQ file. Please select another.');
end
catch
    clear
    Get_Data
end
