Beispiel #1
0
def RunTestWithTimeout(test_timeout, errmsg='Test Timed-out'):
    """
    Context manager to execute tests with a timeout
    :param: test_timeout : int
    :param: errmsg : str
    :rtype: None
    """
    try:
        with TestTimeout(seconds=test_timeout):
            yield
    except Exception:
        LOGGER.exception(errmsg)
        Aqf.failed(errmsg)
        Aqf.end(traceback=True)
Beispiel #2
0
def aqf_plot_channels(
    channelisation,
    plot_filename='',
    plot_title='',
    caption="",
    log_dynamic_range=90,
    log_normalise_to=1,
    normalise=False,
    hlines=None,
    vlines=None,
    ylimits=None,
    xlabel=None,
    ylabel=None,
    plot_type='channel',
    hline_strt_idx=0,
    cutoff=None,
    show=False,
):
    """
        Simple magnitude plot of a channelised result
        return: None

        Example
        -------

        aqf_plot_channels(nomalised_magnintude(dump['xeng_raw'][:, 0, :]),
                          'chan_plot_file', 'Channelisation plot')

        If `channelisation` is a tuple it is interpreted as a multi-line plot with
        `channelisation` containing:

        `((plot1_data, legend1), (plot2_data, legend2), ... )`

        If a legend is None it is ignored.

        if `log_dynamic_range` is not None, a log plot will be made with values normalised
        to the peak value of less than -`log_dynamic_range` dB set to -`log_dynamic_range`

        Normalise log dynamic range to `log_normalise_to`. If None, each line is
        normalised to it's own max value, which can be confusing if they don't all have
        the same max...

        If Normalise = True the maximum log value will be subtracted from the loggerised
        data.

        plot_type:
            channel = Channelisation test plot
            eff     = Efficiency plot
            bf      = Beamformer response plot
        hline_strt_idx:
            Horisontal line colour will be matched to the actual line colour. If multiple
            hlines will be plotted, use this index to indicate at which actual line to
            start matching colours.
    """
    try:
        if not isinstance(channelisation[0], tuple):
            channelisation = ((channelisation, None), )
    except IndexError:
        Aqf.failed('List of channel responses out of range: {}'.format(
            channelisation))
    has_legend = False
    plt_line = []
    try:
        ax = plt.gca()
    except tkinter.TclError:
        LOGGER.exception(
            'No display on $DISPLAY enviroment variable, check matplotlib backend'
        )
        return False

    try:
        vlines_plotd = False
        if len(vlines) > 3:
            annotate_text = vlines[-1]
            vlines = vlines[:-1]

        if type(vlines) is list:
            _vlines = iter(vlines)
        else:
            _vlines = vlines
    except:
        pass

    plt.grid(True)
    for plot_data, legend in channelisation:
        kwargs = {}
        if legend:
            has_legend = True
            kwargs['label'] = legend
        if log_dynamic_range is not None:
            plot_data = loggerise(plot_data,
                                  log_dynamic_range,
                                  normalise_to=log_normalise_to,
                                  normalise=normalise)
            ylbl = 'Channel response [dB]'
        else:
            if plot_type == 'eff':
                ylbl = 'Efficiency [%]'
            else:
                ylbl = 'Channel response (linear)'

        plt_color = ax._get_lines.prop_cycler.next().values()[0]
        try:
            plt_line_obj = plt.plot(plot_data, color=plt_color, **kwargs)
        except tkinter.TclError:
            LOGGER.exception(
                'No display on $DISPLAY enviroment variable, check matplotlib backend'
            )
            return False

        if type(vlines) is list:
            try:
                plt.axvline(x=next(_vlines),
                            linestyle='dashdot',
                            color=plt_color)
                vlines_plotd = True
            except StopIteration:
                pass
            except TypeError:
                plt.axvline(x=_vlines, linestyle='dashdot', color=plt_color)
                vlines_plotd = True

        plt_line.append(plt_line_obj)

    if ylabel:
        plt.ylabel(ylabel)
    else:
        plt.ylabel(ylbl)

    if xlabel:
        plt.xlabel(xlabel)
    else:
        plt.xlabel('Channel number')
        if cutoff:
            msg = ('CBF channel isolation: {:.3f}dB'.format(cutoff))
            plt.axhline(cutoff, color='red', linestyle='dotted', linewidth=1.5)
            plt.annotate(msg,
                         xy=(len(plot_data) / 2, cutoff),
                         xytext=(-20, -30),
                         textcoords='offset points',
                         ha='center',
                         va='bottom',
                         bbox=dict(boxstyle='round, pad=0.2', alpha=0.3),
                         arrowprops=dict(arrowstyle='->',
                                         fc='yellow',
                                         connectionstyle='arc3, rad=0.5',
                                         color='red'))

    if plot_title:
        plt.title(plot_title)

    if ylimits:
        plt.ylim(ylimits)

    if caption:
        plt.figtext(.1,
                    -.25,
                    ' \n'.join(textwrap.wrap(caption)),
                    horizontalalignment='left')

    if vlines_plotd:
        ymid = np.min(plot_data) / 2.
        plt.annotate('',
                     xy=[vlines[0], ymid],
                     xytext=(vlines[1], ymid),
                     arrowprops=dict(arrowstyle='<->'))
        plt.annotate('',
                     xy=[vlines[1], ymid],
                     xytext=(vlines[2], ymid),
                     arrowprops=dict(arrowstyle='<->'))
        plt.text(vlines[0], ymid + 1, annotate_text)

    if hlines:
        if type(hlines) is not list:
            lines = hlines
            msg = ('{:.3f}dB'.format(lines))
            plt.axhline(lines, linestyle='dotted', linewidth=1.5)
        else:
            for idx, lines in enumerate(hlines):
                try:
                    color = plt_line[idx + hline_strt_idx][0].get_color()
                except:
                    color = 'red'
                plt.axhline(lines,
                            linestyle='dotted',
                            color=color,
                            linewidth=1.5)

                if plot_type == 'eff':
                    msg = ('Requirement: {}%'.format(lines))
                elif plot_type == 'bf':
                    msg = ('Expected: {:.2f}dB'.format(lines))
                else:
                    msg = ('{:.2f} dB'.format(lines))

        plt.annotate(msg,
                     xy=(len(plot_data) / 2, lines),
                     xytext=(-20, -30),
                     textcoords='offset points',
                     ha='center',
                     va='bottom',
                     bbox=dict(boxstyle='round, pad=0.2', alpha=0.3),
                     arrowprops=dict(arrowstyle='->',
                                     fc='yellow',
                                     connectionstyle='arc3, rad=0.5',
                                     color='red'))

    if has_legend:
        plt.legend(fontsize=9,
                   fancybox=True,
                   loc='center left',
                   bbox_to_anchor=(1, .8),
                   borderaxespad=0.).set_alpha(0.5)

    Aqf.matplotlib_fig(plot_filename, caption=caption)
    if show:
        fig1 = plt.gcf()  # Get Current Figure
        plt.show(block=False)
        plt.draw()
        fig1.savefig(plot_filename, bbox_inches='tight', dpi=100)
    plt.cla()
    plt.clf()