#!/usr/bin/env python
"""

 Plot jamming detection data.  Either processes
 a single T04 file or else all of the T04 files
 in a specified directory using wildcard.

   This loads rec35:28

 Example:
  ./plt_jamming_detection.py /home/ddelore/DataDir/RX6-2209

  Optional arguments:
    --rt_band       RT band number [defaults to all]
    --ant_num       Antenna number [defaults to #0]
    --s_band        Also plot S-band [if present]
    -p, --power     Plot spectral power rather than band quality
    --save_figs     Save to .png [defaults to OFF]


  Remember your rt_band mapping:
    band  rf_band  rt_band
     L1      0        0
     L2      1        1
     L5      6        4
     E6      7        5
     B1      8        6
     S1     10       11
"""


import os
import argparse
import numpy as np
import matplotlib.pyplot as plt
from pylab import subplots, where, log10, meshgrid, r_, show
from mutils import vd2cls, rt_band_to_label, rt_subband_to_label, rt_subtype_to_label


def plt_jamming_detection(args):

    path_name = args.path_name

    # Grab all T04 files in a directory
    if not path_name.endswith('.T04'):
        path_name = os.path.join(path_name, '*.T04')

    # Open a new figure window
    fig,ax = subplots(3,1,sharex=True)
    ax[0].set_title(path_name)
    ax[0].set_xlabel('GPS TOW [sec]')
    ax[1].set_xlabel('GPS TOW [sec]')
    ax[2].set_xlabel('GPS TOW [sec]')
    if not args.power:
        ax[0].set_ylabel('Band Quality')
        ax[1].set_ylabel('Sub-band Quality')
        ax[2].set_ylabel('Signal Tracking Quality')
    else:
        ax[0].set_ylabel('Band Spectral Power [dB]')
        ax[1].set_ylabel('Sub-band Spectral Power [dB]')
        ax[2].set_ylabel('Signal Tracking Quality')

    # Load rec35:28
    d = vd2cls(path_name, rec='-d35:28')
    print('\n Rec35:sub28 version = ' + str(int(d[0,d.k['VERSION']])) + '\n')

    # Time
    t = d[:].GPS_SEC

    version = int(d[0,d.k['VERSION']])
    n_bands = int(d[0,d.k['MAX_BANDS']])
    n_subbands = int(d[0,d.k['MAX_SUBBANDS']])
    n_subtypes = int(d[0,d.k['MAX_SUBTYPES']])

    ###################################################################
    #
    # Band Quality
    #
    ###################################################################

    # Loop over RT bands
    for rt_band in range(0,12):

        # Did we request all bands
        if (args.rt_band >= 0) and (rt_band != args.rt_band):
            continue

        # Did we request to skip S-band
        if (rt_band == 11) and not args.s_band:
            continue

        if not args.power:
            # Dimension band quality storage
            qual = np.full_like(t,np.nan)
        else:
            # Dimension band power storage
            pwr = np.full_like(t,np.nan)

        # Loop over storage data
        for i in range(n_bands):

            # Get the RT band(s) for this entry
            rt_band_idx = d.k['RT_BAND_%2.2d' %i]

            # Get the antenna number(s) for this entry
            ant_num_idx = d.k['B_ANT_NUM_%2.2d' %i]

            if not args.power:
                # Get the band quality values for this entry
                idx = d.k['BAND_QUALITY_%2.2d' %i]
                temp_qual = d[:,idx]
            else:
                # Get the band power values for this entry
                idx = d.k['B_SPECTRAL_PWR_%2.2d' %i]
                temp_pwr = d[:,idx]

            # Get indexes which match the requested band & antenna
            idx = (d[:,rt_band_idx] == rt_band) \
                & (d[:,ant_num_idx] == args.ant_num)

            if not args.power:
                # Load band quality data
                qual[idx] = temp_qual[idx]
            else:
                # Load band power data
                pwr[idx] = temp_pwr[idx]

        if not args.power:
            # Band Quality
            if np.any(np.isfinite(qual)):
                # offset the values for better legibility
                #                              |
                #                              v
                ax[0].plot( t, qual + (2-rt_band)/20,
                            label=rt_band_to_label(rt_band) )
        else:
            # Band Power
            if np.any(np.isfinite(pwr)):
                pwr[pwr < 0.1] = 0.1
                ax[0].plot( t, 10*log10(pwr),
                            label=rt_band_to_label(rt_band) )

    ax[0].grid()
    ax[0].legend(loc='upper left')
    ax[0].set_xlim(t[0],t[-1])
    if not args.power:
        ax[0].set_ylim(-0.5,+4.5)
    else:
        ax[0].set_ylim(-5,30)

    ###################################################################
    #
    # Sub-band Quality
    #
    ###################################################################

    # Loop over RT sub-bands
    for rt_subband in range(0,11):

        # Did we request to skip S-band
        if (rt_subband == 10) and not args.s_band:
            continue

        if not args.power:
            # Dimension sub-band quality storage
            qual = np.full_like(t,np.nan)
        else:
            # Dimension sub-band power storage
            pwr = np.full_like(t,np.nan)

        # Loop over storage data
        for i in range(n_subbands):

            # Get the RT sub-band(s) for this entry
            rt_subband_idx = d.k['RT_SUBBAND_%2.2d' %i]

            # Get the antenna number(s) for this entry
            ant_num_idx = d.k['S_ANT_NUM_%2.2d' %i]

            # Get which RT band(s) for this entry
            which_rt_band_idx = d.k['WHICH_RT_BAND_%2.2d' %i]

            if not args.power:
                # Get the sub-band quality values for this entry
                idx = d.k['SUBBAND_QUALITY_%2.2d' %i]
                temp_qual = d[:,idx]
            else:
                # Get the sub-band power values for this entry
                idx = d.k['S_SPECTRAL_PWR_%2.2d' %i]
                temp_pwr = d[:,idx]

            # Get indexes which match the requested sub-band & antenna
            idx = (d[:,rt_subband_idx] == rt_subband) \
                & (d[:,ant_num_idx] == args.ant_num)

            # Also cross-reference for requested RT band
            if (args.rt_band >= 0):
                idx = idx & (d[:,which_rt_band_idx] == args.rt_band)

            if not args.power:
                # Load sub-band quality data
                qual[idx] = temp_qual[idx]
            else:
                # Load sub-band power data
                pwr[idx] = temp_pwr[idx]

        if not args.power:
            # Sub-band Quality
            if np.any(np.isfinite(qual)):
                # offset the values for better legibility
                #                                |
                #                                v
                ax[1].plot( t, qual + (2-rt_subband)/20,
                            label=rt_subband_to_label(rt_subband) )
        else:
            # Sub-band Power
            if np.any(np.isfinite(pwr)):
                pwr[pwr < 0.1] = 0.1
                ax[1].plot( t, 10*log10(pwr),
                            label=rt_subband_to_label(rt_subband) )

    ax[1].grid()
    ax[1].legend(loc='upper left')
    ax[1].set_xlim(t[0],t[-1])
    if not args.power:
        ax[1].set_ylim(-0.5,+4.5)
    else:
        ax[1].set_ylim(-5,30)

    ###################################################################
    #
    # Signal Tracking Quality
    #
    ###################################################################

    # Loop over RT sub-types
    for rt_subtype in range(0,38):

        # Dimension tracking quality storage
        qual = np.full_like(t,np.nan)

        # Loop over storage data
        for i in range(n_subtypes):

            # Get the RT sub-type(s) for this entry
            rt_subtype_idx = d.k['RT_SUBTYPE_%2.2d' %i]

            # Get the antenna number(s) for this entry
            ant_num_idx = d.k['T_ANT_NUM_%2.2d' %i]

            # Get which RT band(s) for this entry
            which_rt_band_idx = d.k['T_RT_BAND_%2.2d' %i]

            # Get the tracking quality values for this entry
            idx = d.k['TRACK_QUALITY_%2.2d' %i]
            temp_qual = d[:,idx]

            # Get indexes which match the requested sub-type & antenna
            idx = (d[:,rt_subtype_idx] == rt_subtype) \
                & (d[:,ant_num_idx] == args.ant_num)

            # Also cross-reference for requested RT band
            if (args.rt_band >= 0):
                idx = idx & (d[:,which_rt_band_idx] == args.rt_band)

            # Load tracking quality data
            qual[idx] = temp_qual[idx]

        # Signal Tracking Quality
        if np.any(np.isfinite(qual)):
            # offset the values for better legibility
            #                                |
            #                                v
            ax[2].plot( t, qual + (20-rt_subtype)/100,
                        label=rt_subtype_to_label(rt_subtype) )

    ax[2].grid()
    ax[2].legend(loc='upper left')
    ax[2].set_xlim(t[0],t[-1])
    ax[2].set_ylim(-0.5,+4.5)

    if args.save_figs:
        plt.savefig(os.path.splitext(path_name)[0] + "_rec35:28.png",dpi=150)

    ###################################################################
    #
    # All done, refresh the figure window
    #
    ###################################################################

    show()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
                                     description=__doc__)

    parser.add_argument('path_name', help='name of or path to your T04 file(s)')
    parser.add_argument('--rt_band', type=int, default=-1,
                        help='RT band number [defaults to all]')
    parser.add_argument('--ant_num', type=int, default=0,
                        help='antenna number [defaults to #0]')
    parser.add_argument('--s_band', action='store_true',
                        help='(optional) also plot S-band [if present]')
    parser.add_argument('-p', '--power', action='store_true',
                        help='(optional) plot spectral power rather than band quality')
    parser.add_argument('--save_figs', action='store_true',
                        help='(optional) save to .png [defaults to OFF]')

    args = parser.parse_args()
    plt_jamming_detection(args)

