def start_x_data(self): """ Enable/Start output product capture """ try: assert isinstance(self.katcp_rct, resource_client.ThreadSafeKATCPClientResourceWrapper) reply, informs = self.katcp_rct.req.capture_list(timeout=_timeout) assert reply.reply_ok() self.product_name = [i.arguments[0] for i in informs if self.corr_config['xengine']['output_products'] in i.arguments][0] assert self.product_name is not None LOGGER.info('Capturing %s product' %self.product_name) except Exception: self.product_name = self.corr_config['xengine']['output_products'] LOGGER.exception('Failed to retrieve capture list via CAM interface, got it from config file.' '\nFile:%s Line:%s' % (getframeinfo(currentframe()).filename.split('/')[-1], getframeinfo(currentframe()).lineno)) try: reply, informs = self.katcp_rct.req.capture_start(self.product_name) assert reply.reply_ok() LOGGER.info(' %s' % str(reply)) Aqf.progress(str(reply)+'\n') return True except Exception: LOGGER.exception('Failed to capture start: %s' %str(reply)) return False
def aqf_plot_histogram(data_set, plot_filename='test_plt.png', plot_title=None, caption="", bins=256, ranges=(-1, 1), ylabel='Samples per Bin', xlabel='ADC Sample Bins', show=False): """Simple histogram plot of a data set return: None """ try: plt.grid(True) except tkinter.TclError: LOGGER.exception( 'No display on $DISPLAY enviroment variable, check matplotlib backend' ) return False else: plt.hist(data_set, bins=bins, range=ranges) if plot_title: plt.title(plot_title) plt.ylabel(ylabel) plt.xlabel(xlabel) plt.figtext(.1, -.125, ' \n'.join(textwrap.wrap(caption)), horizontalalignment='left') Aqf.matplotlib_fig(plot_filename, caption=caption) if show: plt.show(block=False) plt.cla() plt.clf()
def executed_by(): """Get who ran the test.""" try: user = pwd.getpwuid(os.getuid()).pw_name if user == 'root': raise OSError Aqf.hop('Test ran by: {} on {} system on {}.\n'.format( user, os.uname()[1].upper(), time.strftime("%Y-%m-%d %H:%M:%S"))) except Exception as e: _errmsg = 'Failed to detemine who ran the test with %s' % str(e) LOGGER.error(_errmsg) Aqf.hop('Test ran by: Jenkins on system {} on {}.\n'.format( os.uname()[1].upper(), time.ctime()))
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)
def stop_x_data(self): """ Disable/Stop output product capture """ try: assert self.product_name is not None assert isinstance(self.katcp_rct, resource_client.ThreadSafeKATCPClientResourceWrapper) reply, informs = self.katcp_rct.req.capture_stop(self.product_name, timeout=_timeout) assert reply.reply_ok() LOGGER.info(' %s' %str(reply)) Aqf.progress(str(reply)) return True except Exception: LOGGER.exception('Failed to capture stop, might be because config file does not contain ' 'Xengine output products.\n: File:%s Line:%s' % ( getframeinfo(currentframe()).filename.split('/')[-1], getframeinfo(currentframe()).lineno)) return False
def aqf_plot_phase_results( freqs, actual_data, expected_data, plot_filename, plot_title='', plot_units=None, caption='', dump_counts=5, show=False, ): """ Gets actual and expected phase plots. return: None """ try: plt.gca().set_prop_cycle(None) except tkinter.TclError: LOGGER.exception( 'No display on $DISPLAY enviroment variable, check matplotlib backend' ) return False if len(actual_data) == dump_counts or len( expected_data) == dump_counts - 1: for phases in actual_data: plt.plot(freqs, phases) else: plt.plot(freqs, actual_data[-1], label='{0:.3f} {1}'.format(np.max(np.abs(actual_data[0])), plot_units)) plt.gca().set_prop_cycle(None) if len(expected_data) == dump_counts or len( expected_data) == dump_counts - 1: if not isinstance(expected_data[0], tuple): expected_data = ((expected_data, None), ) for label_, phases in expected_data: fig = plt.plot(freqs, phases, '--', label='{0:.3f} {1}'.format(label_, plot_units))[0] else: fig = plt.plot(freqs, expected_data[-1], '--', label='{0:.3f} {1}'.format(expected_data[0], plot_units))[0] axes = fig.get_axes() ybound = axes.get_ybound() yb_diff = abs(ybound[1] - ybound[0]) new_ybound = [ybound[0] - yb_diff * 1.1, ybound[1] + yb_diff * 1.1] # plt.vlines(len(freqs) / 2, *new_ybound, colors='b', # linestyles='dotted', label='Center Chan.') plt.title('{}'.format(plot_title)) axes.set_ybound(*new_ybound) plt.grid(True) plt.ylabel('Phase [radians]') plt.xlabel('Channel number') plt.figtext(.1, -.125, ' \n'.join(textwrap.wrap(caption)), horizontalalignment='left') plt.legend() fig1 = plt.gcf() # Get Current Figure Aqf.matplotlib_fig(plot_filename, caption=caption) if show: plt.show() plt.draw() fig1.savefig(plot_filename, bbox_inches='tight', dpi=100) plt.cla() plt.clf()
def aqf_plot_and_save(freqs, data, df, expected_fc, plot_filename, plt_title, caption="", cutoff=None, show=False): try: fig = plt.plot(freqs, data)[0] except tkinter.TclError: LOGGER.exception( 'No display on $DISPLAY enviroment variable, check matplotlib backend' ) return False axes = fig.get_axes() ybound = axes.get_ybound() yb_diff = abs(ybound[1] - ybound[0]) # new_ybound = [ybound[0] - yb_diff * 1.1, ybound[1] + yb_diff * 1.1] new_ybound = [ybound[0] * 1.1, ybound[1] * 1.1] new_ybound = [y if y != 0 else yb_diff * 0.05 for y in new_ybound] plt.vlines(expected_fc, *new_ybound, colors='r', label='Channel Fc') plt.vlines(expected_fc - df / 2, *new_ybound, label='Channel min/max') plt.vlines(expected_fc - 0.8 * df / 2, *new_ybound, label='Channel at +-40%', linestyles='--') plt.vlines(expected_fc + df / 2, *new_ybound, label='_Channel max') plt.vlines(expected_fc + 0.8 * df / 2, *new_ybound, label='_Channel at +40%', linestyles='--') plt.title(plt_title) axes.set_ybound(*new_ybound) try: plt.grid(True) except tkinter.TclError: LOGGER.exception( 'No display on $DISPLAY enviroment variable, check matplotlib backend' ) return False else: plt.ylabel('dB relative to VACC max') # TODO Normalise plot to frequency bins plt.xlabel('Frequency (Hz)') if cutoff: msg = ('Channel isolation: {0:.3f}dB'.format(cutoff)) plt.axhline(cutoff, color='red', ls='dotted', linewidth=1.5, label=msg) plt.figtext(.1, -.125, ' \n'.join(textwrap.wrap(caption)), horizontalalignment='left') plt.legend(fontsize=9, fancybox=True, loc='center left', bbox_to_anchor=(1, .8), borderaxespad=0.) Aqf.matplotlib_fig(plot_filename, caption=caption) if show: plt.show(block=False) plt.cla() plt.clf()
def decorated(*args, **kwargs): meth(*args, **kwargs) Aqf.end(traceback=True)
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()
def test_heading(heading): Aqf.hop('-' * 50) Aqf.stepBold(heading) Aqf.hop('-' * 50)
def test_aqf_decorators_2(self): Aqf.step("Make sure the sensor give us a status.") Aqf.progress("Get status from sensor") # Your code here. status = True Aqf.is_true(status, "Check that sensor status is true") Aqf.waived("This next task has been waived") Aqf.tbd("TBD. Still to do test.") Aqf.wait(2, "Wait to proccess next step") Aqf.step("Set the value of the sensor") Aqf.step('Open KatGUI and observe sensors') Aqf.checkbox( 'On the sensor display and observe that there are sensors') # Your code here. status = False Aqf.is_false(status, "Check that the sensor status is now false") # Aqf.failed("Test failed") Aqf.end()
def test_aqf_decorators(self): Aqf.hop() Aqf.step("Setup") #Aqf.sensor('sim.sensors.asc_wind_speed').get() # Set something on the simulator. Aqf.stepBold("Bold Setup") Aqf.stepline("Underlined Step") Aqf.wait(1) value_from_sensor = 10 Aqf.equals(10, value_from_sensor, 'Test that the sensor has a value of 10') Aqf.more(11, value_from_sensor, "Test that the sensor has a value more than 10") Aqf.less(6, value_from_sensor, "Test that the sensor has a value less than 10") Aqf.step("Set elevation limits") min_ap_elevation = 15.0 max_ap_elevation = 90.0 Aqf.in_range(30, min_ap_elevation, max_ap_elevation, "Check if result falls within expected limits") Aqf.step("Check that result has a value almost equal") Aqf.almost_equals( 10.2, value_from_sensor, 0.5, "Test that the sensor has an almost equal value to 10") Aqf.step("Give Minimum and Maximum Limits for AP Elevation") Aqf.array_almost_equal([15, 90], [min_ap_elevation, max_ap_elevation], "Check max and min elevation") Aqf.step("Check is system in on.") system_on = True Aqf.is_true(system_on, 'Check that the system_on switch is set.') Aqf.step("Read the first message from the system.") ## Your Code here. message = 'hallo world' Aqf.equals('hallo world', message, 'Check that "hallo world" is returned.') message = 'Hello world' Aqf.is_not_equals('hallo world', message, 'Check that "hallo world" is returned.') Aqf.step('Open KatGUI and observe sensors') Aqf.checkbox( 'On the sensor display and observe that there are sensors') Aqf.step("Switch off.") Aqf.skipped("Skipped. We cannot switch the system off at the moment.") Aqf.step("Log into KatGUI") Aqf.keywait("Press Enter to continue") Aqf.step("Test TBD.") Aqf.waived("This next task has been waived") Aqf.tbd("TBD. Still to do test.") Aqf.wait(2, "Wait to proccess next step") Aqf.step("Add line at end of the test") linewidth = 100 Aqf.addLine('_', linewidth) Aqf.end()
def test_aqf_decorators_3(self): Aqf.step("Setup") s = Aqf.sensor('sim.sensors.asc_wind_speed').get() Aqf.progress("The2 sensor was %s" % str(s)) Aqf.sensor('sim.sensors.asc_wind_speed').set(10) s = Aqf.sensor('sim.sensors.asc_wind_speed').get() Aqf.progress("The3 sensor was %s" % str(s)) Aqf.sensor('sim.sensors.asc_wind_speed').set(33, 1, 2) s = Aqf.sensor('sim.sensors.asc_wind_speed').get() Aqf.progress("The3 sensor was %s" % str(s)) Aqf.sensor("cam.m063.sensor.rsc_rsc_vac_pump_running").get() Aqf.waived("This next task has been waived") Aqf.tbd("TBD. Still to do test.") Aqf.wait(2, "Wait to proccess next step") Aqf.step('Open KatGUI and observe sensors') Aqf.checkbox( 'On the sensor display and observe that there are sensors') Aqf.end()