Source code for keyoscacquire.programmes

# -*- coding: utf-8 -*-
"""
Python backend for installed command line programmes. These can also be integrated in python scripts or used as examples.

* :func:`list_visa_devices`: listing visa devices

* :func:`path_of_config`: finding path of config.py

* :func:`get_single_trace`: taking a single trace and saving it to csv and png

* :func:`get_traces_single_connection_loop` :func:`get_traces_connect_each_time_loop`: two programmes for taking multiple traces when a key is pressed, see descriptions for difference

* :func:`get_num_traces`: get a specific number of traces

"""

import sys, logging; _log = logging.getLogger(__name__)
import keyoscacquire.oscacq as acq
import numpy as np
from tqdm import tqdm #progressbar

# local file with default options:
import keyoscacquire.config as config


[docs]def list_visa_devices(ask_idn=True): """Prints a list of the VISA instruments connected to the computer, including their addresses.""" import pyvisa rm = pyvisa.ResourceManager() resources = rm.list_resources() if len(resources) == 0: print("\nNo VISA devices found!") else: print("Found {} resources. Now obtaining information about them..".format(len(resources))) information, could_not_connect = [], [] for i, address in enumerate(resources): # loop through resources to learn more about them current_resource_info = [] info_object = rm.resource_info(address) alias = info_object.alias if info_object.alias is not None else "N/A" current_resource_info.extend((str(i), address, alias)) if ask_idn: try: # open the instrument and get the identity string instrument = rm.open_resource(address) id = instrument.query('*IDN?') current_resource_info.extend(acq.interpret_visa_id(id)) instrument.close() except pyvisa.Error as e: could_not_connect.append(i) current_resource_info.extend(["no connection"]*5) except Exception as ex: print("(i) Got exception %s when asking instrument #%i for identity." % (ex.__class__.__name__, i)) could_not_connect.append(i) current_resource_info.extend(["Error"]*5) information.append(current_resource_info) if ask_idn: # transpose to lists of property nums, addrs, aliases, makers, models, serials, firmwares, model_series = (list(category) for category in zip(*information)) # select what properties to list selection = (nums, addrs, makers, models, model_series, aliases) # name columns header_fields = (' #', 'address', 'maker', 'model', 'series', 'alias') row_format = "{:>{p[0]}s} {:{p[1]}s} {:{p[2]}s} {:{p[3]}s} {:{p[4]}s} {:{p[5]}s}" else: selection = [list(category) for category in zip(*information)] header_fields = (' #', 'address', 'alias') row_format = "{:>{p[0]}s} {:{p[1]}s} {:{p[2]}s}" # find max number of characters for each property to use as padding padding = [max([len(instance) for instance in property]) for property in selection] # make sure the padding is not smaller than the header field length padding = [max(pad, len(field)) for pad, field in zip(padding, header_fields)] header = row_format.format(*header_fields, p=padding) # print the table print("\nVISA devices connected:") print(header) print("="*(len(header)+2)) for info in zip(*selection): print(row_format.format(*info, p=padding))
[docs]def path_of_config(): """Print the absolute path of the config.py file.""" import os print("config.py can be found in:\n\t%s\n" % os.path.dirname(os.path.abspath(__file__)))
[docs]def get_single_trace(fname=config._filename, ext=config._filetype, address=config._visa_address, timeout=config._timeout, wav_format=config._waveform_format, channel_nums=config._ch_nums, source_type='CHANnel', acq_type=config._acq_type, num_averages=config._num_avg, p_mode='RAW', num_points=0): """This programme captures and stores a single trace.""" scope = acq.Oscilloscope(address=address, timeout=timeout) scope.set_options_get_trace_save(fname=fname, ext=ext, wav_format=wav_format, channel_nums=channel_nums, source_type=source_type, acq_type=acq_type, num_averages=num_averages, p_mode=p_mode, num_points=num_points) scope.close() print("Done")
[docs]def get_traces_connect_each_time_loop(fname=config._filename, ext=config._filetype, address=config._visa_address, timeout=config._timeout, wav_format=config._waveform_format, channel_nums=config._ch_nums, source_type='CHANnel', acq_type=config._acq_type, num_averages=config._num_avg, p_mode='RAW', num_points=0, start_num=0, file_delim=config._file_delimiter): """This program consists of a loop in which the program connects to the oscilloscope, a trace from the active channels are captured and stored for each loop. This permits the active channels to be changing thoughout the measurements, but has larger overhead due to establishing and closing a new connection every time. The loop runs each time 'enter' is hit. Alternatively one can input n-1 characters before hitting 'enter' to capture n traces back to back. To quit press 'q'+'enter'. """ n = start_num fnum = file_delim+str(n) fname = acq.check_file(fname, ext, num=fnum) # check that file does not exist from before, append to name if it does print("Running a loop where at every 'enter' oscilloscope traces will be saved as %s<n>%s," % (fname, ext)) print("where <n> increases by one for each captured trace. Press 'q'+'enter' to quit the programme.") while sys.stdin.read(1) != 'q': # breaks the loop if q+enter is given as input. For any other character (incl. enter) fnum = file_delim+str(n) scope = acq.Oscilloscope(address=address, timeout=timeout) x, y, channels = scope.set_options_get_trace(wav_format=wav_format, channel_nums=channel_nums, source_type=source_type, acq_type=acq_type, num_averages=num_averages, p_mode=p_mode, num_points=num_points) acq.plot_trace(x, y, channels, fname=fname+fnum) fhead = scope.generate_file_header(channel_nums) acq.save_trace(fname+fnum, x, y, fileheader=fhead, ext=ext) scope.close() n += 1 print("Quit")
[docs]def get_traces_single_connection_loop(fname=config._filename, ext=config._filetype, address=config._visa_address, timeout=config._timeout, wav_format=config._waveform_format, channel_nums=config._ch_nums, source_type='CHANnel', acq_type=config._acq_type, num_averages=config._num_avg, p_mode='RAW', num_points=0, start_num=0, file_delim=config._file_delimiter): """This program connects to the oscilloscope, sets options for the acquisition and then enters a loop in which the program captures and stores traces each time 'enter' is pressed. Alternatively one can input n-1 characters before hitting 'enter' to capture n traces back to back. To quit press 'q'+'enter'. This programme minimises overhead for each measurement, permitting measurements to be taken with quicker succession than if connecting each time a trace is captured. The downside is that which channels are being captured cannot be changing thoughout the measurements. """ ## Initialise scope = acq.Oscilloscope(address=address, timeout=timeout) scope.set_acquiring_options(wav_format=wav_format, acq_type=acq_type, num_averages=num_averages, p_mode=p_mode, num_points=num_points) ## Select sources sources, sourcesstring, channel_nums = scope.determine_channels(source_type=source_type, channel_nums=channel_nums) fhead = scope.generate_file_header(channel_nums) n = start_num fnum = file_delim+str(n) fname = acq.check_file(fname, ext, num=fnum) # check that file does not exist from before, append to name if it does print("Running a loop where at every 'enter' oscilloscope traces will be saved as %s<n>%s," % (fname, ext)) print("where <n> increases by one for each captured trace. Press 'q'+'enter' to quit the programme.") while sys.stdin.read(1) != 'q': # breaks the loop if q+enter is given as input. For any other character (incl. enter) fnum = file_delim+str(n) x, y = scope.get_trace(sources, sourcesstring) acq.plot_trace(x, y, channel_nums, fname=fname+fnum) # plot trace and save png acq.save_trace(fname+fnum, x, y, fileheader=fhead, ext=ext) # save trace to ext file n += 1 print("Quit") scope.close()
[docs]def get_num_traces(fname=config._filename, ext=config._filetype, num=1, address=config._visa_address, timeout=config._timeout, wav_format=config._waveform_format, channel_nums=config._ch_nums, source_type='CHANnel', acq_type=config._acq_type, num_averages=config._num_avg, p_mode='RAW', num_points=0, start_num=0, file_delim=config._file_delimiter): """This program connects to the oscilloscope, sets options for the acquisition, and captures and stores 'num' traces. """ ## Initialise scope = acq.Oscilloscope(address=address, timeout=timeout) scope.set_acquiring_options(wav_format=wav_format, acq_type=acq_type, num_averages=num_averages, p_mode=p_mode, num_points=num_points, acq_print=False) ## Select sources sources, sourcesstring, channel_nums = scope.determine_channels(source_type=source_type, channel_nums=channel_nums) fhead = scope.generate_file_header(channel_nums) n = start_num fnum = file_delim+str(n) fname = acq.check_file(fname, ext, num=fnum) # check that file does not exist from before, append to name if it does for i in tqdm(range(n, n+num)): fnum = file_delim+str(i) x, y = scope.get_trace(sources, sourcesstring, acquire_print=(i==n)) #acq.plot_trace(x, y, channel_nums, fname=fname+fnum) # plot trace and save png acq.save_trace(fname+fnum, x, y, fileheader=fhead, ext=ext, print_filename=(i==n)) # save trace to ext file print("Done") scope.close()