PyICe package

Subpackages

Submodules

PyICe.LTC_plot module

Marcom Compliant Plot Generator

This program can be used to generate plots for general lab use or to generate Marcom specific plots that can be imported directly into the datasheet in SVG format.

The objects that can be created with this program are:
  1. plot

  2. Page

  3. Multipage_pdf

The basic model is simple. You create one or more plots and add things to them like traces, histograms, legends, arrows, notes, etc. Once your plots are populated you create one or more pages and determine how you want the plots to arrange on each page. For instance you can create an 8.5x11 page and add 9 plots to it in a standard 3x3 grid. You can make one big page if you want. It doesn’t have to be a standard size if you don’t care what the printer does with it and it won’t affect your SVG files to Marcom. If you want to have multiple pages of plots you can create a Mulipage_pdf and add one or more pages to it.

If you want larger plots with just one plot per page as in plot_tools.py you can create a page per plot, add a plot to each page and add all of the pages to a Multipage_pdf.

So to start, you’ll need to create a python work file and import this program: e.g.

 ----------- LTCXXXX_plots.py -------------- 
|import sys                                 |
|sys.path.append("../../../PyICe")          |
|import LTC_plot                            |
|    .                                      |
|    .                                      |
|    .                                      |
 ------------------------------------------- 

Next you want to create your plots. A generally preferable work flow would be to create all of your plots without regard to reference on a Page or Multipage_pdf.

G0 = LTC_plot.plot(
                    plot_title      = "EN/FBIN Thresholds",
                    plot_name       = "8709 G0",
                    xaxis_label     = "TEMPERATURE (" + DEGC + ")",
                    yaxis_label     = "FBIN CHIP ENABLE (V)",
                    xlims           = (-50, 125),
                    ylims           = (1.2, 1.4),
                    xminor          = 0,
                    xdivs           = 7,
                    yminor          = 0,
                    ydivs           = 10,
                    logx            = False,
                    logy            = False)

A plot is nothing more than a record of the plot you want to create. It doesn’t support any outputting methods itself. A plot must eventually be added to a Page to be useful. Only a Page can be generated as an SVG file, even if there’s only one plot on the page.

The arguments of a plot instance are shown below. All plot arguments are required.

plot_title : “string” plot_name : “string” xaxis_label : “string” yaxis_label : “string”

Accepts control characters such as n to start a second line. These text fields also respond to Tex formatting for subscripting There are a few unicode characters available in LTC_plot to help with greek characters and degree signs, etc. Be aware that the Marcom minus sign is not the same as the one you type. You may wan to use LTC_plot.minus.

xlims : (xmin, xmax) ylims : (ymin, ymax)

These two fields also accept python None or string “auto” for automatic scaling. Autoscaling is useful to view the data for the first time and then the final values can be entered later once the data is understood.

xminor0

This is the number of minor X divisions per major X division.

xdivs7

This is the number of major X divisions.

yminor0

This is the number of minor Y divisions per major XY division.

ydivs10

This is the number of major Y divisions.

logxFalse

Sets the X axis to a log scale with locators at [1,2,3,4,5,6,7,8,9].

logyFalse

Sets the Y axis to a log scale with locators at [1,2,3,4,5,6,7,8,9].

Once you have a plot you can add things to it such as:
  • add_trace()

  • add_histogram()

  • add_scatterplot()

  • add_note()

  • add_legend()

  • add_arrow()

  • make_second_y_axis()

The most common element is a trace. You can add as many traces as you like. The same is true of histograms. You can also put traces and histograms on the same plot (for instance to show the Gaussian normal curve).

When you add a trace you have the option to specify line style and marker. Linear datasheets often use dotted or dot dash lines for improved black and white readability but rarely if even use markers so use them judiciously.

Valid linestyles are:
  • ‘-’

  • ‘–’

  • ‘-.’

  • ‘:’

and valid markers are:
  • ‘:’

  • ‘.’

  • ‘,’

  • ‘o’

  • ‘v’

  • ‘^’

  • ‘<’

  • ‘>’

  • ‘1’

  • ‘2’

  • ‘3’

  • ‘4’

  • ‘8’

  • ‘s’

  • ‘p’

  • ‘*’

  • ‘h’

  • ‘H’

  • ‘+’

  • ‘x’

  • ‘D’

  • ‘d’

  • ‘|’

  • ‘_’

  • TICKLEFT

  • TICKRIGHT

  • TICKUP

  • TICKDOWN

  • CARETLEFT

  • CARETRIGHT

  • CARETUP

  • CARETDOWN

Please see matplotlib docs online for more details.

Trace colors currently supported are:
  • LT_RED_1

  • LT_BLUE_1

  • LT_GREEN_1

  • LT_COPPER_1

  • LT_BLACK

  • LT_COPPER_2

  • LT_RED_2

  • LT_BLUE_2

  • LT_GREEN_2

  • LT_YELLOW_2

  • LT_BLUE_2_40PCT

  • LT_RED_1_40PCT

You can make your own colors by entering a list of RGB colors (r,g,b), all of which should be between 0 and 1 rather than 0 to 255. This is strongly discouraged however, as it will not be in compliance with LTC standards and should not make its way to Marcom.

add_legend takes arguments:
  • axis

  • location

  • justification

  • use_axes_scale

axis

The axis from which the legend items have been added.

location

Coordinates in an xy list (x, y) of where to place the legend. These are relative, see use_axes_scale.

justification
Justification of the test of the legend. Accepts:
  • “best”

  • “upper right”

  • “upper left”

  • “lower left”

  • “lower right”

  • “right”

  • “center left”

  • “center right”

  • “lower center”

  • “upper center”

  • “center”

use_axes_scale:

True means place the legend by the scale of the data values whereas False means use values from 0 to 1 representing data independent percentage of the graph size.

Notes, on the other hand, need to have coordinates given. Both support the use_axes_scale argument which defaults to True referencing the item to the data values rather than as a percentage (0..1) of the graph limits.

Data can come from a number of sources such as a CSV file or a .sqlite database and should be a zipped list of (x,y) values for a trace and just a list for a histogram. Consult the examples file for details.

You can also add as many notes as you like. The position of the notes can be set by either referring them to the axes_scale, a scale relative to your data or a percentage scale (0..1) of the axes extents. The default is to use the scale of your data. This should be easier to help you locate the notes, etc as the graticules will more precisely help you picture where the item will be.

You can only add one legend. For each trace on a given axis, it will place a label preceded by a line stub in the same color and width of the trace. Generally the legend will placed along side the axis to which it belongs but you can specify where it goes.

An arrow is based on the matplotlib annotate() object and consists of a text box with an arrow emanating from it. You control where the lower left corner of the text goes as well as the arrow tip.

If you add a second y axis you have to, once again, specify a few required items in a similar manner to when you created the plot: 1) yaxis_label 2) ylims 3) yminor 4) ydivs 5) logy

As you add traces and histograms you’ll need to specify to which axis they belong (1 or 2).

Once you have created all of your plots you will need to add them to a page:

Page1 = Page(rows_x_cols = (3, 3), page_size = (8.5, 11))

Defaults for rows_x_cols = (1, 1) and for page_size is None. If you omit the page_size or specify None, the page will shrink to fit the plots you add to it. If, on the other hand, you specify a page size and the plots you add to it don’t quite fit, the plots will overlap a bit. That won’t matter for datasheet importation as you’ll see later. Alternately, if your plots are swimming on your page, they’ll be spread out to roughly fill the Page.

Pages support the following methods:
  1. add_plot()

  2. create_pdf()

  3. create_svg()

  4. kit_datasheet()

add_plot() has options to change the plot size on the page such as plot_sizex and plot_sizey. These values are extremely specific to datasheets and should not be changed if the plots are to be sent to Marcom. It’s best to enter the plot instance and position and leave the rest alone.

Page1.add_plot(G01, position = 1)
Page1.add_plot(G02, position = 2)
Page1.add_plot(G03, position = 3)

As you add plots to the page with a given position, the plots appear on the page top to bottom, left to right.

So a Page that was specified as 3x3 would add up to 9 plots in the following order:

 ---------------------------
|                           |
|   [1]     [2]     [3]     |
|                           |
|                           |
|   [4]     [5]     [6]     |
|                           |
|                           |
|   [7]     [8]     [9]     |
|                           |
 ---------------------------

Or a 2x2 Page would be positioned as:

 -------------------
|                   |
|   [1]     [2]     |
|                   |
|                   |
|   [3]     [4]     |
|                   |
 -------------------
Pages support the following methods:
  1. create_pdf(“LTCXXXX_Page1”)

  2. create_svg(“LTCXXXX_Page1”)

  3. kit_datasheet(“LTCXXXX_Page1”)

Each of these takes just a file_basename. The file extension is added to match the output.

All output data you request is place in a newly created folder under your work area called “/plots”.

kit_datasheet() performs the following sequence for you:
  1. Creates a zip file.

  2. Creates a disposable page.

  3. Adds one plot that is found on your Page.

  4. Creates an SVG file of the disposable page and adds it to the zip file.

  5. Repeats for each plot on your Page. The disposable Page evaporates.

  6. Creates a PDF of your entire page for reference and dumps it in the zip file.

If you end up needing more than one page of plots you can add your pages to a Multipage_pdf:

LTCXXXX_typcurves = Multipage_pdf("LTCXXXX_typcurves")
LTCXXXX_typcurves.add_page(Page1)
LTCXXXX_typcurves.add_page(Page2)
LTCXXXX_typcurves.kit_datasheet()
Multipage_pdfs support the methods:
  1. kit_datasheet(“LTCXXXX_Page1”)

  2. create_pdf(“LTCXXXX_Page1”)

To really get going and find more example see:

PyICeExamplesLTC_plot_exampleLTC_plot_example.py

* TIP *

If you get a warning about missing Linear fonts and you have them installed, try deleting: “C:\Users\%username%\.matplotlib\fontList.cache and tex.cache”

PyICe.LTC_plot.CMYK_to_fracRGB(CMYK)
class PyICe.LTC_plot.Multipage_pdf

Bases: object

Add one or more Pages to a Multipage_pdf to keep your page sizes manageable (such as 8.5x11). Multipage_pdf also support kit_datasheet().

add_page(page)
create_pdf(file_basename)
kit_datasheet(file_basename='datasheet_kit')
class PyICe.LTC_plot.Page(rows_x_cols=None, page_size=None, plot_count=None)

Bases: object

LTC_LOG10_Formatter(x)
add_plot(plot, position=None, plot_sizex=None, plot_sizey=None, left_border=0.7, right_border=0.7, top_border=0.7, bottom_border=0.7, x_gap=1, y_gap=1, trace_width=None)
create_pdf(file_basename, filepath=None)
create_svg(file_basename=None, filepath=None)
kit_datasheet(file_basename='datasheet_kit')
class PyICe.LTC_plot.PyICe_data_base(table_name, file_name='data_log.sqlite')

Bases: object

PyICe.LTC_plot.RGB_to_fracRGB(RGB)
PyICe.LTC_plot.RGB_to_webRGB(RGB)
class PyICe.LTC_plot.color_gen(rollover=True)

Bases: object

Color yielding generator. Returns a new color each time an instance is called

reset()

start color sequence over

PyICe.LTC_plot.data_from_file(filename)
PyICe.LTC_plot.fracRGB_to_CMYK(RGB)
PyICe.LTC_plot.fracRGB_to_RGB(fracRGB)
PyICe.LTC_plot.fracRGB_to_webRGB(fracRGB)
PyICe.LTC_plot.list_markers()

Valid linestyles are [‘-’ ‘–’ ‘-.’ ‘:’ ‘None’ ‘ ‘ ‘’] Valid markers are [‘:’ ‘.’ ‘,’ ‘o’ ‘v’ ‘^’ ‘<’ ‘>’ ‘1’ ‘2’ ‘3’ ‘4’ ‘8’ ‘s’ ‘p’ ‘*’ ‘h’ ‘H’ ‘+’ ‘x’ ‘D’ ‘d’ ‘|’ ‘_’ TICKLEFT TICKRIGHT TICKUP TICKDOWN CARETLEFT CARETRIGHT CARETUP CARETDOWN]

class PyICe.LTC_plot.plot(plot_title, plot_name, xaxis_label, yaxis_label, xlims, ylims, xminor, xdivs, yminor, ydivs, logx, logy)

Bases: object

add_arrow(text, text_location, arrow_tip, use_axes_scale=True, fontsize=7)

Adds a note and an arrow pointing to something. The arrow shaft emanates from the center of the note text and the arrow tip lands on the arrow top point. Both position follow either the data axes and absolute axes.

add_histogram(axis, xdata, num_bins, color, normed=False, legend='', edgecolor='black', linewidth=0.5, alpha=1)
add_horizontal_line(value, xrange=None, note=None, axis=1, color=[1, 0, 0])

This can be useful for annotating limit lines. It can make dotted red lines for example.

add_legend(axis, location=(0, 0), justification='lower left', use_axes_scale=False, fontsize=7)

PLace a legend on the graph. The legend labels were acquired from the legend argument in the add_trace call. Position supports data axes and absolute axes.

add_note(note, location=[0.05, 0.5], use_axes_scale=True, fontsize=7, axis=1, horizontalalignment='left', verticalalignment='bottom')

Add an arbitratry note anywhere on the graph. Position supports data axes and absolute axes.

add_scatter(axis, data, color, marker='*', markersize=4, legend='', stepped_style=False, vxline=False, hxline=False)
add_trace(axis, data, color, marker=None, markersize=0, linestyle='-', legend='', stepped_style=False, vxline=False, hxline=False)
add_vertical_line(value, yrange=None, note=None, axis=1, color=[1, 0, 0])

This can be useful for annotating limit lines. It can make dotted red lines for example.

create_csv(file_basename, filepath=None, dialect='excel')
create_svg(file_basename)

shortcut to create SVG for a single plot without having to construct a Page.

make_second_y_axis(yaxis_label, ylims, yminor, ydivs, logy)

A second (right side) y axis is useful if two very different data sets need to be plotted against the same indepdendent axis. Be sure to use the same number of divisions on each y-axis to have sensible (common) graticules.

class PyICe.LTC_plot.scope_plot(plot_title, plot_name, xaxis_label, xlims, ylims)

Bases: plot

add_all_time_refmarkers(xlocation_open, xlocation_closed)
add_horizontal_line(value, xrange=None, note=None, color=[1, 0, 0])

This can be useful for annotating limit lines. It can make dotted red lines for example.

add_legend(axis=1, location=(0, 0), justification='lower left', use_axes_scale=False, fontsize=7)

PLace a legend on the graph. The legend labels were acquired from the legend argument in the add_trace call. Position supports data axes and absolute axes.

add_ref_marker(ylocation, marker_color, use_axes_scale)
add_time_refmarker_closed(xlocation)
add_time_refmarker_open(xlocation)
add_trace(data, color, marker=None, markersize=0, linestyle='-', legend='')
add_trace_label(trace_label, ylocation, use_axes_scale)
add_vertical_line(value, yrange=None, note=None, color=[1, 0, 0])

This can be useful for annotating limit lines. It can make dotted red lines for example.

make_second_y_axis(*args, **kwargs)

A second (right side) y axis is useful if two very different data sets need to be plotted against the same indepdendent axis. Be sure to use the same number of divisions on each y-axis to have sensible (common) graticules.

PyICe.LTC_plot.smooth(data, window=5)
PyICe.LTC_plot.smooth_y_vector(data, window=5)
PyICe.LTC_plot.webRGB_to_RGB(webRGB)
PyICe.LTC_plot.webRGB_to_fracRGB(webRGB)

PyICe.TypicalCurveEditor_input module

PyICe.generate_docs module

PyICe.interpolator module

PyICe.ivy_instruments module

PyICe.lab_core module

Channel and Threading Core Framework

changes to this file should be minimal!

exception PyICe.lab_core.ChannelAccessException

Bases: ChannelException

Attempt to write non-writable channel or read non-readable channel.

exception PyICe.lab_core.ChannelAttributeException

Bases: ChannelException

Attempt to read non-existent channel attribute.

exception PyICe.lab_core.ChannelException

Bases: Exception

Parent of all channel exceptions. Not used directly.

exception PyICe.lab_core.ChannelNameException

Bases: ChannelException

Attempt to create invalid channel name.

exception PyICe.lab_core.ChannelReadException

Bases: ChannelException

Out-of-band return value to signal that channel read failed. Should only be used to indicate partial failures within delegated reads. Not typically raised, just instantiated and returned.

exception PyICe.lab_core.ChannelValueException

Bases: ChannelException

Attempt to write a channel beyond min or max limits.

exception PyICe.lab_core.IntegerChannelValueException

Bases: ChannelException

Attempt to write an integer channel to a non-integer value.

exception PyICe.lab_core.RegisterFormatException

Bases: ChannelException

Attempt to apply non-existent channel format.

exception PyICe.lab_core.RemoteChannelGroupException

Bases: ChannelException

Connection problem with remote channel group client.

class PyICe.lab_core.channel(name, read_function=None, write_function=None)

Bases: delegator

The base channel object.

It can be read and/or written. Attributes can also be stored in it. For example channel number in a multi channel instrument

add_change_callback(change_callback=None)

Adds a change callback.

This is a function that will be called any time the channel value changes due to a read or write. The callback function takes two arguments (channel_object, data). If change_callback is unspecified, channel name, value and time will be printed to the terminal each time the channel value changes.

add_preset(preset_value, preset_description=None)

base channels only have unnamed presets (not enumerations)

add_read_callback(read_callback)

Adds a read callback.

This is a function that will be called any time the channel is read. The callback function takes two arguments (channel_object, data)

add_tag(tag)

each channel may receive several tags for sorting purposes. The tag is usually a string.

add_tags(tag_list)

each channel may receive several tags for sorting purposes. This function adds a list of tags. The tags are usually strings.

add_write_callback(write_callback)

Adds a write callback.

This is a function that will be called any time the channel is written. The callback function takes two arguments (channel_object, data)

property cached_value

Retrieve last read or written channel value

static default_print_callback(channel, value)
delay(dly_time)

delay method. Broken out of write method so that it can be sub-classed if necessary.

format_display(data)

converts data to string according to string formatting rule set by self.set_display_format_str()

get_attribute(attribute_name)

retrieve value previously set with set_attribute(attribute_name, value)

get_attributes()

return dictionary of all channel attributes previously set with set_attribute(attribute_name, value)

get_category()

returns category membership. should be a string.

get_description()

return channel description string.

get_max_write_limit()

return max writable channel value.

get_max_write_warning()

return max warning channel value.

get_min_write_limit(formatted=False)

return min writable channel value.

get_min_write_warning(formatted=False)

return min warngin channel value.

get_name()

return channel name

get_preset_description(preset_name)

Returns description associated with preset_name

get_presets()

Returns a list of preset names

get_presets_dict()

Returns a dictionary of preset names and value

get_size()
get_tags(include_category=True)

returns the list of tags for this channel. If include_category is True the list will also include the category

get_type_affinity()
get_write_delay()

return automatic delay after channel write

get_write_history()
has_preset_descriptions()

returns boolean value of whether any presets have a description

is_changed()

returns boolean status of whether channel value is different from previously read/written value (once per change)

is_readable()

return register readability boolean

is_writeable()

return register writability boolean

property previous_cached_value

Retrieve second last read or written channel value

read()
read_without_delegator(force_data=False, data=None, **kwargs)
remove_change_callback(change_callback=None)
set_attribute(attribute_name, value)

set attribute_name to value value can be retrived later with get_attribute(attribute_name)

set_category(category)

each channel may be a member of a single category for sorting purposes. category argument is usually a string

set_description(description)

sets the channel description. argument is string

set_display_format_function(function)

abandon string formatting and pass data through custom user-supplied function

set_display_format_str(fmt_str='', prefix='', suffix='')

format string to alter how data is displayed.

example ‘3.2f’, ‘04X’, ‘#06X’, ‘#18b’, ‘.2%’ prefix will be displayed immediately before the channel data, example ‘0x’ suffix will be displayed immediately after the channel data, example ‘ A’ or ‘ V’

set_max_write_limit(max)

set channel’s maximum writable value. None disables limit

set_max_write_warning(max)

set channel’s maximum writable warning value. None disables limit

set_min_write_limit(min)

set channel’s minimum writable value. None disables limit

set_min_write_warning(min)

set channel’s minimum writable value warning. None disables limit

set_name(name)

rename channel

set_read_access(readable=True)

set or unset register read access

set_write_access(writeable=True)

set or unset register write access

set_write_delay(delay)

sets the automatic delay in seconds after channel write

set_write_resolution(decimal_digits=None)

set automatic rounding to fixed number of decimal digits, appropriate to the instrument being controlled. for instance, it probably doesn’t make much sense to set a power supply to much better than 1mV (3) resolution a frequency generator might not have better than 1ns (9) or 100ps (10) digit resolution. One frequent cause of excessive apparent resolution is scaling numbers by multiplication/division, log-stepping, or other operations likely to create unrepresentable numbers. There are two known likely problems with excessive resolution:

  1. It’s possible to choke the input parsee of test equipment if it has limited input buffer size for the command

  2. Recalling forced values from a SQLite database can be problematic. The answer returned from a get_distict() query can’t be fed back into a WHERE clause to return the same data.

    Something gets truncated inconsistently either in the SQLIte C library itself or in the SQLite Python bindings. Avoiding getting close to machine epsilon (roughly 15 significant decimal digits for double-precision float) robustly addresses the problem.

This decimal treatment might not be appropraite for all use cases. The same effect could be achieved with a more generalized function call if necessary (TBD/TODO).

write(value)
write_unformatted(value)

bypass unformatting stub. Only useful for integer and register channels. intended for use by GUI.

class PyICe.lab_core.channel_access_wrapper(channel_group)

Bases: object

syntatic sugar object to access channels in a channel_group (or master) a channel_group (or master) returns the channel object in response to indexing by channel name this gives an object that wraps a channel_group the the channels themselves are access by index names. master_instance[‘channel_name’] returns the channel object channel_access_wrapper_instance[‘channel_name’] returns the channel value channel_access_wrapper_instance[‘channel_name’]= value writes the value of channel to value

class PyICe.lab_core.channel_group(name='Unnamed Channel Group')

Bases: object

add(channel_or_group)
clone(name=None, categories=None)

Builds a flattened group and tries to reconnect to the remote_channels

If not None, categories list argument acts as a filter - including only channels matching elements of categories.

copy()
debug_print(indent=' ')
get_all_channel_names(categories=None)
get_all_channels_dict(categories=None)
get_all_channels_list(categories=None)
get_all_channels_set(categories=None)
get_categories()
get_channel(channel_name)
get_channel_groups()
get_flat_channel_group(name=None)

returns a channel_group directly containing all channels this one can resolve

get_name()
get_threaded_results(work_units)
merge_in_channel_group(channel_group_object)

merges in a channel group

read(channel_name)
read_all_channels(categories=None, exclusions=[])

read all readable channels in channel group and return orderd dictionary of results. Optionally filter by list of categories.

read_channel(channel_name)
read_channel_list(channel_list)
read_channels(item_list)

item list is a list of channel objects, names or channel_groups

remove_all_channels_and_sub_groups()
remove_categories(*categories)
remove_category(category)
remove_channel(channel)
remove_channel_by_name(channel_name)
remove_channel_group(channel_group_to_remove)
remove_channel_list(item_list)
remove_sub_channel_group(sub_channel_group)
resolve_channel_list(item_list)

takes a list of channels, channel_names, or channel_groups and produces a single channel group

set_name(name)
sort(deep=True, **kwargs)
start_threads(number)
threaded_read_function()
write(channel_name, value)
write_channel(channel_name, value)
write_channels(item_list)
write_html(file_name=None, verbose=True, sort_categories=False)

return html document string and optionally write to file_name if verbose, include tables of presets and attributes for each channel if sort_categories, group channel names first by category before alphabetical sort of channel name

class PyICe.lab_core.channel_master(name=None)

Bases: channel_group, delegator

Master channel collection. There is typically only one. It replaces the old lab_bench as the main point of interaction with channels. Channels and channel_groups (instruments) may be added to it. It also creates dummy and virtual channels and adds them to its collection. It also supports virtual_caching channels; these can use cached data if available during logging or other multiple channel read.

add(channel_or_group)
add_channel_counter(channel_name, **kwargs)

Add a named counter channel. Returns zero the first time channel is read and increments by one each time thereafter.

add_channel_delta_timer(channel_name, reciprocal=False)

Add a named timer channel. Returns the time elapsed since the prior channel read. Optionally, compute 1/time to return frequency instead.

add_channel_dummy(channel_name, integer_size=None)

Add a named dummy channel. This can be used if a single physical instrument channel is externally multiplexed to multiple measurement nodes. The user can store the multiple measurement results from a single instrument into multiple dummy channels. Also it is useful for logging test conditions.

add_channel_total_timer(channel_name)

Add a named timer channel. Returns the time elapsed since first channel read.

add_channel_virtual(channel_name, read_function=None, write_function=None, integer_size=None)

Adds a channel named channel_name. Channel may have a read_function or a write_function but not both. If write_function is supplied, the write function is called with the value when written, and the last written value is returned when read. If read_function is supplied, this channel returns the return of read_function when read. If integer_size is not None, creates in integer_channel instead of a channel. integer_size should specify the number of data bits. Integer channels can add presets, formats.

add_channel_virtual_caching(channel_name, read_function=None, write_function=None, integer_size=None)

Adds a channel named channel_name. Channel may have a read_function or a write_function but not both. If write_function is supplied, the write function is called with the value when written, and the last written value is returned when read. If read_function is supplied, this channel returns the return of read_function when read. If the read_function calls the creating channel_master’s read_channel on another channel, a cached value may be used if part of a multi-channel channel read. This can improve logging speed in some cases.

add_read_callback(read_callback)

Adds a read callback. This is a function that will be called any time a channel(s) is read. the callback function should accept one argument: the dictionary of results. If it is not important to group results by each batch read, consider adding a callback to an individual channel instead.

add_write_callback(write_callback)

Adds a write callback. This is a function that will be called any time a channel is written. the callback function should accept one argument: the dictionary of results. In this case, the dictionary will only contain a key,value pair for the single channel that was written. For more flexibility, considering adding a callback to an individual channel instead.

attach(address='localhost', port=5001, authkey=b'ltc_lab')
background_gui(cfg_file='default.guicfg')
get_dummy_clone()
gui(cfg_file='default.guicfg')
read_channel(channel_name)
read_channel_list(channel_list)
read_delegated_channel_list(channel_list)
remove_read_callback(read_callback)
remove_write_callback(write_callback)
serve(address='localhost', port=5001, authkey=b'ltc_lab')
write_channel(channel_name, value)

Delegates channel write to the appropriate registered instrument.

class PyICe.lab_core.delegator

Bases: object

base class for a read delegator, this is the lowest level class in the library. You will probably never use it directly.

add_interface(interface)
get_delegator()
get_interfaces()
lock_interfaces()
read_delegated_channel_list(channel_list)
resolve_delegator()
set_allow_threading(state=True)
set_delegator(delegator)
threadable()
unlock_interfaces()
write_delegated_channel_list(channel_value_list)
class PyICe.lab_core.instrument(name)

Bases: channel_group

Superclass for all lab instruments To add an instrument to a lab_bench object, it must inherit from instrument or one of its specialized subclasses

Rules for adding instruments:
  1. extend instrument class

  2. call the instrument classes __init__ from its __init__

  3. contain an add_channel (and/or add_channel_XXXXX) methods that:
    1. create a channel object with a:
      1. name

      2. EITHER a read_function or write_function

    2. call the _add_channel method with that channel as an argument

  4. has a name attribute which is a meaningful string about the instrument

add_channel(channel_name)
Usage: Add channel name to instrument. For multi-channel instruments,

typically also takes a second argument representing the physical channel of the instrument. May also take channel configuration arguments specific to the instrument.

Operation: This method should create the channel object then call self._add_channel(channel) to add it to the internal channel group

Method must be overloaded by each instrument driver.

add_interface_raw_serial(interface_raw_serial, timeout=None, baudrate=None)
add_interface_spi(interface_spi, timeout=None, baudrate=None)
add_interface_twi(interface_twi, timeout=None)
add_interface_visa(interface_visa, timeout=None)
get_error()

Return the first error from the instrument. Overload in scpi_instrument or the actual instrument class

get_errors()

Return a list of all errors from the instrument. Overload in scpi_instrument or the actual instrument class

get_interface(num=0)
set_category(category_name, update_existing_channels=False)
class PyICe.lab_core.integer_channel(name, size, read_function=None, write_function=None)

Bases: channel

Channel with integer value limitation.

Adds presets and formats but retains channel class’s read/write restrictions.

add_format(format_name, format_function, unformat_function, signed=False, units='', xypoints=[])

Add a format to this register. Formats convert a raw number into a more meaningful string and vice-versa Formats can be generic hex, bin, etc, or can be more complicated. format_name is the name of the format format_function transforms from integer data to real unformat_function transforms from real data to integer format_function and unformat_function should be reversible signed treats integer data as two’s complement with self.size bit width units optionally appended to formatted (real) data when displayed by GUI xypoints optionally allows duplicates information from format/unformat function to allow reproduction of transform in SQL, etc

add_preset(preset_name, preset_value, preset_description=None)

Adds a preset named preset_name with value preset_value

format(data, format, use_presets)

take in integer data, pass through specified formatting function, and return string/real representation.

format_read(raw_data)

transform from integer to real units according to using_presets_read() and active format

format_write(value)

transform from real units to integer according to using_presets_write() and active format

get_format()

return active format as set by set_format(format)

get_formats()

Return a list of format_names associate with this register. The format_string elements of the returned list may be passed to the format or unformat methods

get_max_write_limit(formatted=False)

return max writable channel value. If formatted, return max writeable value in transformed units accorting to set_format(format) active format.

get_min_write_limit(formatted=False)

return min writable channel value. If formatted, return min writeable value in transformed units accorting to set_format(format) active format.

get_size()
get_units(format)

return real units string for specified format. ex ‘A’ or ‘V’

read_without_delegator(force_data=False, data=None, **kwargs)

read intercept to apply formats/presets to channel (raw) read

remove_format(format_name)

remove format_name from dictionary of available formats

set_format(format)

set active transformation format. reads and writes happen in transformed (real) units instead of native integer. Set to None to disable formatting.

signedToTwosComplement(signed)

transform signed integer to two’s complement formatted binary number. Requires register’s size attribute to be set in __init__

sql_format(format, use_presets)

return SQL legal column selection text for insertion into a query/view

twosComplementToSigned(binary)

transform two’s complement formatted binary number to signed integer. Requires register’s size attribute to be set in __init__

unformat(string, format, use_presets)

take in formatted string / real, pass through specified unformatting function, and return integer representation.

use_presets_read(bool)

enable replacement of integer value with named enum when reading channel

use_presets_write(bool)

enable replacement of named enum with integer value when writing channel

using_presets_read()

return boolean denoting last setting of use_presets_read()

using_presets_write()

return boolean denoting last setting of use_presets_write()

write(value)

write intercept to apply formats/presets before channel write. Coerce to integer and warn about rounding error. Also accepts None

write_unformatted(value)

bypass unformatting. intended for use by GUI.

class PyICe.lab_core.logger(channel_master_or_group=None, database='data_log.sqlite', use_threads=True)

Bases: master

add_channel(channel_object)
add_data_channels(data_dictionary)

prepare logger channel group with fake channels matching data_dictionary keys. call before logger.new_table(). use to log previously collected data in conjunction with logger.log_data()

add_log_callback(log_callback)

Adds a read callback. This is a function that will be called any time a channel(s) is read. the callback function should accept one argument: the dictionary of results. If it is not important to group results by each batch read, consider adding a callback to an individual channel instead.

append_table(table_name)
check_data_changed(data, compare_exclusions=[])

return True if data is different than self._previously_logged_data. Shared test between several log_if_changed methods.

check_format_name(format_name)
copy_table(old_table, new_table)
create_format_view(use_presets=True)
execute(sql_query, *params)

Execute arbitrary SQL statements on database. Not capable of returning results across thread boundary. Useful to set up views, indices, etc

flush()

commit pending transactions and block until database thread queue is empty.

get_data()
get_database()
get_master()
get_table_name()
log(exclusions=[])

measure all non-excluded channels. Channels may be excluded by name, channel_group(instrument), or directly. Returns a dictionary of what it logged.

log_data(data_dictionary, only_if_changed=False)

log previously collected data. data_dictionary should have channel name keys. set up logger and table using logger.add_data_channels() alternately, data_dictionary can be an iterable containing dictionaries, each representing a single row.

log_if_changed(log_exclusions=[], compare_exclusions=[])

like log(), but only stores data to database if data in at least on channel/column has changed. log_exclusions is a list of logger channels which will not be read nor stored in the database. compare_exclusions is a list of logger channels which will not be used to decide if data has changed but which will be read and stored in the databased if something else changed. rowid and datetime are automatically excluded from change comparison. returns channel data if logged, else None

log_kwdata(**kwargs)

log previously collected data, but provided as keyword key,value pairs instead of dictionary.

log_many(data_iter_of_dictionaries)
new_table(table_name, replace_table=False, warn=False)

create a new table with columns matching channels known to logger instance if replace_table == ‘copy’, previously collected data to a new table with the date and time appended to the table name before overwriting if replace_table, allow previously collected data to be overwritten if not replace_table, raise an exception (or print to screen instead if warn) rather than overwrite existing data

optimize()

Defragment database file, reducing file size and speeding future queries. Also re-runs query plan optimizer to speed future queries. WARNING: May take a lot time to complete when operating on a large database. WARNING: May re-order rowid’s

query(sql_query, *params)
remove_log_callback(log_callback)
set_journal_mode(journal_mode='WAL', synchronous='NORMAL', timeout_ms=10000)

configure database connection for more reliable concurrent read/write operations with high data throughput or large data sets. Three options are individually configurable:

journal_mode changes the default rollback journal to other methods which read-lock the database less often and for less time. WAL (write-ahead log) is usually the best choice. Reading and writing are independet and will never block each other. https://www.sqlite.org/pragma.html#pragma_journal_mode https://www.sqlite.org/wal.html

synchronouns changes how SQLite waits to confirm that data has been safely written to the disk platter surface. Relaxing this from FULL to NORMAL to OFF will increase commit speed with an increasing risk of data corruption if power is lost or the compute crashes at an inopportune time. Use with caution. Usually WAL alone will correct most access problems. https://www.sqlite.org/pragma.html#pragma_synchronous

timeout_ms changes the amount of time SQLite will wait for access to a locked database before giving up and failing. Timeouts are much less likely in WAL mode compated to normal rollback journal mode. https://www.sqlite.org/pragma.html#pragma_busy_timeout

stop()

close sqlite database connection.

switch_table(table_name)
class PyICe.lab_core.logger_backend(database='data_log.sqlite', use_threads=True)

Bases: object

append_table(table_name, columns)
check_exception()
copy_table(old_table, new_table)
classmethod db_clean(column_data)

help database to store lists, dictionaries and any other future datatype that doesn’t fit natively

execute(sql_query, *params)

not currently capable of returning the query result through the thread queue useful for setting up the database with PRAGMA commands.

new_table(table_name, columns, replace_table=False, warn=False)
stop()
store(data)
storemany(data)
switch_table(table_name)
sync_threads()
class PyICe.lab_core.master(name=None)

Bases: channel_master, interface_factory

class PyICe.lab_core.register(name, size, read_function=None, write_function=None)

Bases: integer_channel

Integer channel with read/write restriction removed.

Models remote (volatile) memory. IE, reads must check remote copy rather than use cache like ordinary integer channels. This behavior can be modified on a channel-by-channel basis to speed up communication with the enable_cached_read method.

enable_cached_read()

return last written value rather than read remote memory contents. Essentially reverts from register to writable integer_channel.

class PyICe.lab_core.remote_channel(proxy_channel, parent_delegator)

Bases: channel

methods_to_proxy = ['__str__', 'add_format', 'add_preset', 'format', 'format_read', 'format_write', 'get_format', 'get_formats', 'get_max_write_limit', 'get_min_write_limit', 'get_presets', 'get_presets_dict', 'get_units', 'remove_format', 'set_format', 'signedToTwosComplement', 'twosComplementToSigned', 'unformat', 'use_presets_read', 'use_presets_write', 'using_presets_read', 'using_presets_write', 'write', 'write_unformatted', 'add_tag', 'add_tags', 'add_read_callback', 'add_write_callback', 'format_display', 'get_attribute', 'get_attributes', 'get_category', 'get_description', 'get_name', 'get_tags', 'get_write_delay', 'get_write_history', 'is_readable', 'is_writeable', 'read', 'set_attribute', 'set_category', 'set_description', 'set_display_format_function', 'set_display_format_str', 'set_max_write_limit', 'set_min_write_limit', 'set_name', 'set_read_access', 'set_write_access', 'set_write_delay', 'sql_format']
class PyICe.lab_core.remote_channel_group_client(address='localhost', port=5001, authkey=b'ltc_lab')

Bases: channel_group, delegator

clone()

Builds a flattened group and tries to reconnect to the remote_channels

If not None, categories list argument acts as a filter - including only channels matching elements of categories.

read_delegated_channel_list(channel_list)
class PyICe.lab_core.remote_channel_group_server(channel_group_object, address='localhost', port=5001, authkey=b'ltc_lab')

Bases: object

serve_forever()
class PyICe.lab_core.results_ord_dict

Bases: OrderedDict

Ordered dictionary for channel results reporting with pretty print addition.

class PyICe.lab_core.scpi_instrument(name)

Bases: instrument

SCPI Instrument Base Class. Implements methods common to all SCPI instruments Instruments which adhere to the SCPI specification should inherit from the scpi_instrument class rather than the instrument class.

beep()

Send a beep command.

clear_status()

Send the *CLS command.

display_clear()

Clear the instrument display

display_off()

Turn the instrument display off

display_on()

Turn the instrument display on

display_text(text='')

Display text on instrument front panel

enable_serial_polling()

Enable the instrument to report operation complete via serial polling

error(interface=None)

Get error message.

fetch()

Send FETCH? query.

flush(buffer)
get_error(interface=None)

Return the first error from the SCPI instrument. +0 is the errorcode for no error

get_errors(interface=None)

Return a list of all accumulated SCPI instrument errors.

get_interface(num=0)
identify()

Send the *IDN? command.

init()

Send INIT command.

initiate_measurement(enable_polling=False)

Initiate a measurement

operation_complete()

query if current operation is done blocks i/o until operation is complete or timeout this method retries query until a character is returned in cas of premature timeout EDIT - delet retry for now

read_measurement()

Send FETCH? query.

reset()

Send the *RST command.

trigger()

Send the *TRG command.

PyICe.lab_instruments module

PyICe.lab_interfaces module

Physical Communication Interfaces Hierarchy Manager

Required for multithreaded communication.

class PyICe.lab_interfaces.SerialTestHarness(bytestream, max_bytes_returned_per_read=None)

Bases: object

A harness for testing code that reads and parses input from PySerial serial.Serial objects. A SerialTestHarness emulates a PySerial serial.Serial object by providing a read() method and a writable timeout property. bytestream is a generator function that yields one byte of test stimulus each time its next() method is called. WARNING: Not thread-safe. TODO: The write() method currently implemented does nothing.

static biased_rng(min_val, max_val)
inWaiting()

Returns in_waiting. Added for PySerial <3.0 compatibility.

property in_waiting

How many bytes we promise are available for reading. Generated randomly upon request, this will never exceed the max_bytes_returned_per_read optionally set during object instantiation.

property max_bytes_returned_per_read
read(numbytes)

Returns up to numbytes bytes from our test suite’s bytestream generator, with random delay that’s within timeout.

property timeout
write(bytestring)
PyICe.lab_interfaces.byteify(s)
class PyICe.lab_interfaces.communication_node(*args, **kwargs)

Bases: object

The purpose of this is to map a network of communication resources to each channel

com_node_get_all_descendents()
com_node_get_children()
com_node_get_root()
com_node_register_child(child)
debug_com_nodes(indent='')
get_com_parent()
group_com_nodes_for_threads(sets=None)

returns a list of sets of com_nodes, each set must be communicated with in 1 thread because upstream interfaces are not thread safe

group_com_nodes_for_threads_filter(com_node_list)

takes a list of interfaces and returns a list of lists the returned list are interfaces that cannot be used concurrently each is an ideal candidate for a thread to handle make sure all interface’s root resolves back here

lock()

Lock this communication node to prevent concurrent use, then recursively acquire locks of this communication node’s parents.

set_com_node_parent(parent)
set_com_node_thread_safe(safe=True)
unlock()

Release all parent locks starting with this node’s oldest ancestor. Finish by unlocking this com node.

class PyICe.lab_interfaces.gpib_adapter(*args, **kwargs)

Bases: communication_node

class PyICe.lab_interfaces.gpib_adapter_visa(*args, **kwargs)

Bases: gpib_adapter

class PyICe.lab_interfaces.interface(name, **kwargs)

Bases: communication_node

base class all lab instruments should in some way talk to, all have a timeout whether or not it does anything

class PyICe.lab_interfaces.interface_bobbytalk(name)

Bases: interface

Base class for all interfaces that talk bobbytalk packets and provide the bobbytalk API methods shown here.

handle_comms()

Call this periodically to receive packets from the underlying interface and dispatch to any registered packet handlers (or “modules”)

recv_packet(dest_id, timeout, src_id=None)

Blocks for up to timeout waiting for packet matching dest_id and optionally src_id, continuing to receive and dispatch other incoming packets. Upon success, returns a bobbytalk_packet object. Upon timeout, returns None.

register_handler(dest_id, handler_function)

Sets the handler function for received packets with dest_id. handler_function will be called like this: handler_function(bobbytalk_packet)

send_packet(src_id, dest_id, buffer)

Returns immediately indicating SUCCESS (True) or FAIL (False). Returns SUCCESS if buffer successfully sent to the underlying interface. Otherwise FAIL, meaning the underlying interface couldn’t accept buffer for some reason.

class PyICe.lab_interfaces.interface_bobbytalk_raw_serial(raw_serial_interface, fifo_size=65536, junk_bytes_dump=None, debug=False)

Bases: interface_bobbytalk

Sends and receives bobbytalk packets over a raw serial interface.

handle_comms()

Call this periodically to receive packets from the serial line and dispatch to any registered packet handlers (“modules”) in the module_table.

recv_packet(dest_id, timeout, src_id=None, receive_tries=8)

Blocks for up to timeout waiting for packet matching dest_id and optionally src_id, continuing to receive and dispatch other incoming packets. Upon success, returns a bobbytalk_packet object. Upon timeout, returns None.

register_handler(dest_id, handler_function)

Sets the handler function for received packets with dest_id. handler_function will be called like this: handler_function(bobbytalk_packet)

send_packet(src_id, dest_id, buffer)

Returns immediately indicating SUCCESS (True) or FAIL (False). Returns SUCCESS if buffer successfully sent to the underlying interface. Otherwise FAIL, meaning the underlying interface couldn’t accept buffer for some reason.

class PyICe.lab_interfaces.interface_factory

Bases: communication_node

The interface factory is a wrapper class that creates interfaces and the instruments inheriting from “communication_node”, that they pass on to channels.

Interfaces acquired through the interface factory have a notion of a “parent” which traces back to the physical port of the computer. The parent feature allows the user to request multiple interfaces from the factory without regard for possible collisions that may occur with multiple endpoints talking through the same physical channel (e.g. COM port, USB port, etc.).

PyICe will ensure that channels that trace back to a common parent, with a common underlying hardware pointer, will be singulated serially within the threading (during logging for instance) such that all channels will be read sequentially with possibility of a collision in time.

It should be clear from this that all requests for a physical interface should be made from the interface factory itself using these “get_xxx” methods rather than reaching around and grabbing raw interface handles directly. If you do that, you are on your own and PyICe won’t help you with interface threading problems.

This class ventures to be smart about the interfaces and to simplify their creation. Its purpose is also to encourage portable code, and to remove some low level responsibilities from the instruments.

There are two use models that can be adopted:

  1. An interface_factory can be instantiated and all interfaces acquired from it using the getter methods. Lab instrument objects, created from the lab_instruments folder, then get their interface handles from interfaces acquired from the interface factory object. These instruments are then usually added to a lab core channel_master for channel aggregation.

  2. Alternatley, the project can go straight to creating a lab_core master (not channel_master). A lab_core master is merely a channel_master that inherits this interface_factory class. In this work flow, interfaces can be acquired from that master object directly (again using the getter methods in this class) without the requirement to create a disposable interface_factory instance. This method results in slightly compacted code but has an interface object flow that seems to double back on itself.

get_dummy_interface(parent=None, name='dummy interface')

used only for testing the core lab functions

get_interface_ftdi_d2xx()
get_interface_libusb(idVendor=4722, idProduct=32772, timeout=1)
get_interface_stream_serial(interface_raw_serial)
get_interface_test_harness_serial(serial_port_name, bytestream, timeout=1.0, max_bytes_returned_per_read=7)

Get a PyICified SerialTestHarness, a hardware-free PySerial serial.Serial emulator that provides a read() method and a writable timeout property. bytestream is a generator function that yields one byte of test stimulus each time its next() method is called.

get_labcomm_raw_interface(comport_name, src_id, dest_id, baudrate, timeout)
get_labcomm_twi_interface(comport_name, src_id, dest_id, baudrate, timeout)
get_raw_serial_interface(serial_port_name, baudrate=None, timeout=None, **kwargs)
get_spi_cfgpro_interface(serial_port_name, uart_timeout=None, CPOL=0, CPHA=0, spi_baudrate=1000000.0, ss_ctrl=None)

The configurator Pro (or XT) is an ADI specific breakout board that interfaces test equipment and ICs in a semi-standardized manner.

get_spi_dc590_interface(serial_port_name, uart_baudrate=None, uart_timeout=None, ss_ctrl=None, **kwargs)
get_spi_dummy_interface(delay=0)
get_tcp_serial_interface(dest_ip_address, dest_tcp_portnum, timeout)
get_twi_bobbytalk_raw_serial(serial_port_name, src_id, baudrate=None, fifo_size=1048576, debug=False, **kwargs)

serial_port_name: “COM27” or “/dev/ttyS01”, for example. src_id: 16-bit integer to use as the default source ID in outgoing bobbytalk packets. baudrate: sets the serial link baudrate. fifo_size: sets the size, in bytes, of the FIFO used to buffer packets

coming in over the serial link for packet validation, parsing , and dispatch.

**kwargs: All other keyword arguments are passed to the twi_interface.i2c_bobbytalk constructor,

allowing optional settings like dest_id (defaults to 0x0020 SMBUS module), recv_timeout, cmd_retries, per_cmd_recv_retries…

For testing purposes, if a lab_interface.interface object is passed as the serial_port_name argument, it will be used as if it were a PySerial serial.Serial object. This allows injection of test bytes and other stimuli to the bobbytalk parser.

get_twi_bobbytalk_tcp(dest_ip_address, dest_tcp_portnum, src_id, timeout=0.3, fifo_size=1048576, debug=False, **kwargs)

Talk bobbytalk over TCP/IP given a destination IP address and TCP port number. Uses PySerial’s “socket://” feature to open a TCP/IP socket. dest_ip_address: “127.0.0.1” or “10.15.127.127”, for example. dest_tcp_portnum: 65500, for example. src_id: 16-bit integer to use as the default source ID in outgoing bobbytalk packets. timeout: how long to wait on read or write requests before returning failure fifo_size: sets the size, in bytes, of the FIFO used to buffer packets

coming in over the serial link for packet validation, parsing , and dispatch.

**kwargs: All other keyword arguments are passed to the twi_interface.i2c_bobbytalk constructor,

allowing optional settings like dest_id (defaults to 0x0020 SMBUS module), recv_timeout, cmd_retries, per_cmd_recv_retries…

For testing purposes, if a lab_interface.interface object is passed as the dest_ip_address argument, it will be used as if it were a PySerial serial.Serial object, and the dest_tcp_portnum is ignored. This allows injection of test bytes and other stimuli to the bobbytalk parser.

get_twi_buspirate_interface(serial_port_name, baudrate=None, timeout=None)
get_twi_dc590_serial(serial_port_name, baudrate=None, timeout=None)
get_twi_dummy_interface(delay=0, timeout=None, **kwargs)
get_twi_firmata_interface(firmata_instance)
get_twi_kernel_interface(bus_number)
get_twi_mdump_interface(data_source, **kwargs)
get_twi_scpi_interface(serial_port_name, baudrate=None, timeout=None)
get_twi_scpi_sp_interface(serial_port_name, portnum, sclpin, sdapin, pullup=False, baudrate=None, timeout=None)
get_twi_scpi_testhook_interface(serial_port_name, baudrate=None, timeout=None)
get_visa_gpib_interface(gpib_adapter_number, gpib_address_number, timeout=None)
get_visa_interface(visa_address_string, timeout=None)
get_visa_serial_interface(serial_obj_or_port_name, baudrate=None, timeout=None, **kwargs)
get_visa_tcp_ip_interface(host_address, port, timeout=None, **kwargs)
get_visa_telnet_interface(host_address, port, timeout=None)
get_visa_usbtmc_interface(address, timeout)
get_visa_vxi11_interface(address, timeout)
set_gpib_adapter_visa(adapter_number)
class PyICe.lab_interfaces.interface_ftdi_d2xx

Bases: interface_stream

write this if you want it https://pypi.python.org/pypi/pylibftdi

class PyICe.lab_interfaces.interface_labcomm_raw_serial(raw_serial_interface, serial_port_name, src_id, dest_id)

Bases: interface

Sends and receives Labcomm packets over a raw serial interface.

receive_packet()
send_payload(payload)
set_destination_id(dest_id)
set_source_id(src_id)
class PyICe.lab_interfaces.interface_labcomm_twi_serial(raw_serial_interface, comport_name, src_id, dest_id)

Bases: i2c_labcomm, interface_twi

set_destination_id(dest_id)
set_source_id(src_id)
class PyICe.lab_interfaces.interface_libusb(idVendor, idProduct, timeout)

Bases: interface

Bulk transfer through LibUSB/WinUSB. Implementation may be overly specific to George B’s Direct590 protocol and may need additional options or subclassing later. Transfers must be in multiples of this 64 byte payload size or will result in a babble error in the underlying library. Requires PyUSB: https://github.com/walac/pyusb

read()
write(byte_list)

Send byte_list across subclass-specific communication interface.

class PyICe.lab_interfaces.interface_raw_serial(port_name_or_url, baudrate, timeout, **kwargs)

Bases: interface, serial_from_name_or_url

get_serial_port_name()
read(size, *args, **kw)

Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.

read_raw(size, *args, **kw)
readline(*args, **kw)

Read and return a line from the stream.

If size is specified, at most size bytes will be read.

The line terminator is always b’n’ for binary files; for text files, the newlines argument to open can be used to select the line terminator(s) recognized.

write(msg, *args, **kw)

Output the given byte string over the serial port.

write_raw(msgbytes, *args, **kw)
class PyICe.lab_interfaces.interface_spi(name, **kwargs)

Bases: interface

class PyICe.lab_interfaces.interface_spi_cfgpro(visa_interface, CPOL, CPHA, baudrate=1000000.0, ss_ctrl=None)

Bases: interface_spi, spi_cfgpro

class PyICe.lab_interfaces.interface_spi_dc590(interface_stream, ss_ctrl=None)

Bases: interface_spi, spi_dc590

class PyICe.lab_interfaces.interface_spi_dummy(delay=0)

Bases: interface_spi, spi_dummy

class PyICe.lab_interfaces.interface_stream(name, **kwargs)

Bases: interface

Generic parent class of all stream-type interfaces. Developed for DC590 board variants, but probably has more generic utility if moved into lab_interfaces Maybe consider change to inherit from https://docs.python.org/2/library/io.html

abstract close()

close the underlying interface if necessary

abstract read(byte_count)

Read and return tuple (byte_count bytes, byte_count remaining_bytes) from subclass-specific communication interface. If fewer than byte_count bytes are available, return all available.

abstract write(byte_list)

Send byte_list across subclass-specific communication interface.

class PyICe.lab_interfaces.interface_stream_serial(interface_raw_serial)

Bases: interface_stream

PySerial based stream wrapper.

close()

close the underlying interface

read(byte_count)

Read and return tuple (byte_count bytes, byte_count remaining_bytes) from subclass-specific communication interface. If fewer than byte_count bytes are available, return all available. If byte_count is None, return all available.

write(byte_list)

Send byte_list across subclass-specific communication interface.

class PyICe.lab_interfaces.interface_tcp_serial(dest_ip_address, dest_tcp_portnum)

Bases: interface

Opens a new TCP socket to (IP, port) and presents a PySerial-like PyICe interface to it.

This class’s API mimics enough of interface_raw_serial’s API to be compatible with PyICe code expecting such. For example read(), write(), and timeouts are supported, but it is meaningless to set things like baudrate or parity bits.

close(*args, **kwargs)
get_serial_port_name()
inWaiting()

Returns in_waiting. Added for PySerial <3.0 compatibility.

property in_waiting
read(*args, **kwargs)
property timeout
write(*args, **kwargs)
class PyICe.lab_interfaces.interface_test_harness_serial(serial_port_name, bytestream, max_bytes_returned_per_read=4096)

Bases: interface, SerialTestHarness

get_serial_port_name()
class PyICe.lab_interfaces.interface_twi(name, **kwargs)

Bases: interface

class PyICe.lab_interfaces.interface_twi_bobbytalk(bobbytalk_interface, src_id, **kwargs)

Bases: i2c_bobbytalk, interface_twi

class PyICe.lab_interfaces.interface_twi_buspirate(interface_serial, timeout)

Bases: i2c_buspirate, interface_twi

class PyICe.lab_interfaces.interface_twi_dc590_serial(interface_serial, timeout)

Bases: i2c_dc590, interface_twi

class PyICe.lab_interfaces.interface_twi_dummy(delay, **kwargs)

Bases: interface_twi, i2c_dummy

class PyICe.lab_interfaces.interface_twi_firmata(firmata_instance)

Bases: i2c_firmata, interface_twi

class PyICe.lab_interfaces.interface_twi_mdump(data_source=None, **kwargs)

Bases: interface_twi, mem_dict

class PyICe.lab_interfaces.interface_twi_scpi(interface_serial, timeout)

Bases: i2c_scpi, interface_twi

class PyICe.lab_interfaces.interface_twi_scpi_sp(interface_serial, portnum, sclpin, sdapin, pullup_en=False, timeout=1)

Bases: i2c_scpi_sp, interface_twi

class PyICe.lab_interfaces.interface_twi_scpi_testhook(interface_serial, timeout)

Bases: i2c_scpi_testhook, interface_twi

class PyICe.lab_interfaces.interface_visa(name, **kwargs)

Bases: interface

class PyICe.lab_interfaces.interface_visa_direct(visa_address_string, timeout)

Bases: interface_visa, visa_interface

class PyICe.lab_interfaces.interface_visa_serial(interface_raw_serial_object)

Bases: visa_wrapper_serial, interface_visa

class PyICe.lab_interfaces.interface_visa_tcp_ip(host_address, port, timeout, **kwargs)

Bases: interface_visa, visa_wrapper_tcp

class PyICe.lab_interfaces.interface_visa_telnet(host_address, port, timeout)

Bases: interface_visa, visa_wrapper_telnet

class PyICe.lab_interfaces.interface_visa_usbtmc(address, timeout)

Bases: interface_visa, visa_wrapper_usbtmc

class PyICe.lab_interfaces.interface_visa_vxi11(address, timeout)

Bases: interface_visa, visa_wrapper_vxi11

class PyICe.lab_interfaces.serial_from_name_or_url(*args, **kwargs)

Bases: Serial

PyICe.lab_interfaces.strify(bs)

PyICe.lab_utils module

PyICe.plot_tools module

PyICe.spi_instrument module

Channel Wrapper for SPI Devices

class PyICe.spi_instrument.spiInstrument(name, spiInterface, write_shift_register=None, read_shift_register=None, preamble_clk_cnt=0, preamble_data=0)

Bases: instrument, delegator

Instrument wrapper for basic linear shift register SPI port. Not appropriate for context-sensitive (sub addressed) memory directly. Instead, use multiple spiInstrument copies with appropriate preamble_clk_cnt and preamble_data settings.

add_channel_transceive_enable(channel_name)

Add channel to enable/disable SPI port communication. This can be used to serially change multiple bit fields before sending the data to the SPI slave with a single transaction. Note that communication is disabled independent of this setting if not all writable bit fields have been initialized. Also note that after communication is enabled, a SPI transceive will not take place until a bit field is read or written.

read_delegated_channel_list(channels)

private

PyICe.spi_interface module

SPI Interface Hardware Drivers

Created on Feb 23, 2015 Heavily modified August 2016 to be more generic.

@author: JKapasi @author: DSimmons

The SPI interface is composed of two separate classes:

  1. shift_register

    abstracts individual bit-fields into integer representing contents of full-length shift register

  2. spiInterface: Defines the hardware interface including baudrate, mode (CPOL/CPHA), CS operation.

    Specific hardware implementations should overload this class and implement _shift_data method.

exception PyICe.spi_interface.SPIMasterError

Bases: Exception

class PyICe.spi_interface.shift_register(name='')

Bases: object

helper class to assemble multiple bit-fields together into a single larger integer and to disassemble received data into individual bit-fields.

add_bit_field(bit_field_name, bit_field_bit_count, description='')

build SPI shift register data protocol sequentially MSB->LSB with repeated calls to add_bit_field

copy(prepend_str='', append_str='', keep_name=False)

return new shift register with identical structure to self, but with bit field names augmented with prepend_str and append_str

by default, shift register name will also be augmented with prepend_str and append_str. Suppress this behavior by setting keep_name=False.

display()

print ascii register structure graphic

get_description(key)

return bit field description string

get_name()

return shift register name

keys()

return list of bit-field names registered with instance

pack(bit_field_data_dict)

pack bit fields into single larger integer. also return accumulated clk_count. Suitable for passing directly to spiInterface.transceive(*shift_register.pack(bit_field_data_dict)) bit_field_data_dict should contain one key-value pair for each defined bit_field

unpack(data)

unpack single integer representing full-width shift register data into individual bit field values according to instance-defined boundaries. return dictionary with key-value pairs for each defined bit_field_name and bit_field data.

class PyICe.spi_interface.spiInterface(CPOL, CPHA, ss_ctrl, word_size)

Bases: object

static pack(data_list, word_size=8)

pack byte,word aligned pieces (list) from communication hardware into single integer comprising full shift register width. integer can then be broken up by shift_register object into bit field aligned pieces.

set_ss_ctrl(ss_ctrl_function)

change ss_ctrl function after instantiation. function should take single boolean argument. If true, assert slave select. If false, deassert slave select. There will typically be a logic inversion inside ss_ctrl to achieve active low _cs.

set_strict_alignment(strict)

If true, enforce that SPI master and slave hardware lengths match. If false, enable automatic padding to correct alignment.

transceive(data, clk_count)

send data word out MOSI with clk_count clocks. return word of same size read simultaneously on MISO. Frame entire transaction with slave select.

unpack(data, bit_count, word_size=8)

break full shift register width integer into byte,word aligned pieces. Return list of pieces MS first, LS last. helper to send byte-aligned pieces to hardware even if bit fields span bytes (or 1-bit, 16-bit 32-bit, etc words for other hardware)

class PyICe.spi_interface.spi_bbone(CPOL, CPHA, ss_ctrl, word_size)

Bases: spiInterface

The Beaglebone black will use the Adafruit BBIO, thus we can initialize this package for all purposes This instrument probably got a broken when the parent class interface was modified to support multiple interface hardware boards and more general SPI communication. Needs testing/repair.

class PyICe.spi_interface.spi_bitbang(SCK_channel, MOSI_channel=None, MISO_channel=None, SS_channel=None, CPOL=0, CPHA=0, SS_POL=0, low_level=0, high_level=1)

Bases: spiInterface

cs(select)

select is active low

set_levels(low=0, high=1)

set values to write to SCK_channel, MOSI_channel and SS_channel. values are also used to digitize MISO_channel readings. for example, to use a power supply at 5V logic levels set high=5

class PyICe.spi_interface.spi_buspirate(interface_raw_serial, CPOL=0, CPHA=0, baudrate=1000000.0, ss_ctrl=None)

Bases: spiInterface

cs(select)

select is active low

set_baudrate(baudrate)
set_mode()
class PyICe.spi_interface.spi_cfgpro(visa_interface, CPOL, CPHA, baudrate=1000000.0, ss_ctrl=None)

Bases: spiInterface

cs(select)
class PyICe.spi_interface.spi_dc590(interface_stream, ss_ctrl=None)

Bases: spiInterface

init_spi()
set_cs(level)

control DC590 CS pin. If true, pin high. No active low inversion here.

set_gpio(level)

control DC590 Pin 14 GPIO pin as output. If true, pin high.

spi_mode()

Switch DC590 I2C/SPI mux to SPI

class PyICe.spi_interface.spi_dummy(delay=0, word_size=1)

Bases: spiInterface

cs(select)

PyICe.twi_instrument module

Channel Wraper for SMBus Compliant Devices

Can automatically populate channels/reisters from XML description

class PyICe.twi_instrument.pmbus_instrument(interface_twi, except_on_i2cInitError=True, except_on_i2cCommError=False, retry_count=5, PEC=False)

Bases: twi_instrument

add_register(name, addr7, page, command_code, size, offset, word_size, is_readable, is_writable)
read_delegated_channel_list(register_list)
set_page(page)
class PyICe.twi_instrument.twi_instrument(interface_twi, except_on_i2cInitError=True, except_on_i2cCommError=False, retry_count=5, PEC=False)

Bases: instrument, delegator

add_channel_ARA(name)
add_register(name, addr7, command_code, size, offset, word_size, is_readable, is_writable, overwrite_others=False)
create_format(format_name, format_function, unformat_function, signed=False, description=None, units='', xypoints=[])

Create a new format definition or modify an existing definition.

format_function should take a single argument of integer raw data from the register and return a version of the data scaled to appropriate units. unformat_function should take a single argument of data in real units and return an integer version of the data scaled to the register LSB weight. If the data is signed in two’s-complement format, set signed=True. After creating format, use set_active_format method to make the new format active.

enable_cached_read(include_readable_registers=False)

disable remote read of writable register and instead return cached previous write. only affects write-only register by default. include_readable_registers argument also includes read-write registers.

get_bitfield_writeback_data(addr7, data, command_code, size, offset, word_size)
get_command_codes(register_list)
get_constant(constant)

Sets the constants found in the datasheet used by the formatters to convert from real world values to digital value and back.

get_readable_command_codes(register_list)

returns list of command codes required to read all readable registers within register_list not used for normal delegated reads. helpful to construct command code list for use with other tools (Linduino streaming for example)

list_constants()

Returns the list of constants found in the datasheet used by the formatters to convert from real world values to digital value and back.

populate_from_file(xml_file, format_dict={}, access_list=[], use_case=None, channel_prefix='', channel_suffix='')

xml_register parsing accepts xml input complying with the following DTD (register_map.dtd):

<!– Visit http://en.wikipedia.org/wiki/Document_Type_Definition for an excellent explanation of DTD syntax –> <!ELEMENT register_map (chip+, use*, format_definitions?)> <!ELEMENT chip (description, address+, command_code*)> <!ELEMENT address EMPTY> <!ELEMENT command_code (description?, access+, bit_field+)> <!ELEMENT access EMPTY> <!ELEMENT bit_field (description, default?, preset*, format*)> <!ELEMENT description (#PCDATA)> <!ELEMENT default (#PCDATA)> <!ELEMENT preset (description?)> <!ELEMENT format EMPTY> <!ELEMENT use (category+)> <!ELEMENT category (#PCDATA)> <!ELEMENT format_definitions (format_definition+)> <!ELEMENT format_definition (description, transformed_units?, piecewise_linear_points?)> <!ELEMENT transformed_units (#PCDATA)> <!ELEMENT piecewise_linear_points (point,point+)> <!ELEMENT point EMPTY> <!ATTLIST chip name CDATA #REQUIRED word_size CDATA #REQUIRED> <!ATTLIST address address_7bit CDATA #REQUIRED> <!ATTLIST command_code name ID #REQUIRED value CDATA #REQUIRED> <!ATTLIST bit_field name ID #REQUIRED size CDATA #REQUIRED offset CDATA #REQUIRED category CDATA #REQUIRED> <!ATTLIST access mode CDATA #REQUIRED type (read | write) #REQUIRED> <!ATTLIST preset name CDATA #REQUIRED value CDATA #REQUIRED> <!ATTLIST format name IDREF #REQUIRED> <!ATTLIST use name CDATA #REQUIRED> <!ATTLIST format_definition name ID #REQUIRED signed (True | False | 1 | 0) #REQUIRED> <!ATTLIST point native CDATA #REQUIRED transformed CDATA #REQUIRED>

populate_from_yoda_json_bridge(filename, i2c_addr7, extended_addressing=False)
read_delegated_channel_list(register_list)
set_constant(constant, value)

Sets the constants found in the datasheet used by the formatters to convert from real world values to digital value and back.

class PyICe.twi_instrument.twi_instrument_dummy

Bases: twi_instrument

use for formatters, etc without having to set up a master and physical hardware.

class PyICe.twi_instrument.twi_register(name, size, read_function=None, write_function=None)

Bases: register

calculate_cc_merge_bf(bf_data)

PyICe.twoWireInterface module

PyICe.virtual_instruments module

exception PyICe.virtual_instruments.ExpectException

Bases: Exception

Base class for expect instrument comparison failures

exception PyICe.virtual_instruments.ExpectOverException

Bases: ExpectException

expect instrument comparison failures for measured > expect

exception PyICe.virtual_instruments.ExpectUnderException

Bases: ExpectException

expect instrument comparison failures for measured < expect

exception PyICe.virtual_instruments.ServoException

Bases: Exception

Special expcetion for the servo instrument

exception PyICe.virtual_instruments.ThresholdFinderError

Bases: Exception

non-specific threshold finder error.

exception PyICe.virtual_instruments.ThresholdUndetectableError

Bases: ThresholdFinderError

Threshold finder unable to detect threshold. Perhaps the search range is wrong or perhaps the threshold doesn’t exist. Not used for general configuration errors that should almost never be caught.

class PyICe.virtual_instruments.accumulator(init=0)

Bases: instrument

Virtual accumulator instrument. Writable channel adds value to stored total. Readable channel returns accumulation total. Can be used as a counter by writing accumulation value to +/-1

accumulate(value)

Adds value to accumulation total. Use with caution outside channel framework.

add_channel_accumulate(channel_name)

Channel writes accumulate value into total previously accumulated quantity.

add_channel_accumulation(channel_name)

Channel reads return total accumulated quantity.

class PyICe.virtual_instruments.aggregator

Bases: instrument

Combines multiple, less capable channels into a single channel of great renown.

add_channel(channel_name, slave_channels, sequential=True)

Adds the main channels that will make use of the lesser channels

add_channel_parallel(channel_name, slave_channels)
add_channel_sequential(channel_name, slave_channels)
class PyICe.virtual_instruments.calibrator(verbose=False)

Bases: instrument

Calibrator virtual instrument. Corrects channel’s read/write values based on either two-point gain/offset correction or full lookup table. Requires Numpy for least squares computation during calibration measurement. Can be used without Numpy if gain/offset numbers are supplied from elsewhere.

add_channel_calibrated_2point(channel_name, forcing_channel, gain=None, offset=None, calibration_filename=None, **kwargs)

correct channel writes by previously determined 2-point gain/offset trim. Can pass in **calibrate() to get gain/offset measurements. offset and gain are specified in the direction of readback channel to forcing channel. ie forcing channel error.

add_channel_calibrated_spline(channel_name, forcing_channel, calibration_filename=None, **kwargs)

correct channel writes by previously determined mapping (from calibrate()). Can pass in **calibrate() to get cal map, store results dict locally, or use pickle file. Requires scipy.interpolate.UnivariateSpline

calibrate(forcing_channel, readback_channel, forcing_values, results_filename=None)

produce calibration table and gain/offset calculation for later use by 2point and spline calibrators

class PyICe.virtual_instruments.clipboard

Bases: instrument

Virtual instrument to exchange data with Windows/Linux clipboard for interactive copy and paste with another application.

add_channel_copy(channel_name)

Place data written to channel_name onto clipboard.

add_channel_paste(channel_name)

Place data from clipboard into channel_name.

register_copy_channel(channel_object, write_copy=True)

Automatically places results on clipboard each time channel_object is read and optionally when channel_object is written.

class PyICe.virtual_instruments.delay_loop(strict=False, begin=True, no_drift=True)

Bases: delay_loop, instrument

instrument wrapper for lab_utils.delay_loop enables logging of delay diagnostic variables

add_channel_achieved_loop_time(channel_name)

actual time spent during in last loop iteration possibly longer than requested loop time if user taskes exceeded requested time (overrun).

add_channel_count(channel_name)

total number of times delay() method called

add_channel_delay_margin(channel_name)

time remaining after user’s loop tasks completed to sleep before start of next cycle. Negative if user tasks exceed loop time and no time is left to sleep. Includes any make-up contribution if previous iterations over-ran allocated loop time with no_drift attribute set.

add_channel_total_time(channel_name)

total number of seconds since delay() method first called

class PyICe.virtual_instruments.differencer(init=None)

Bases: instrument

Virtual differencer instrument. Compute_difference channel is writable and causes computation of first difference from last written value. Read_difference channel is read-only and returns computed difference. A readable channel from a different instrument can be registered with this instrument so that any read of that channel causes its value to be differenced automatically without requiring an explicit call to this instrument’s difference method.

add_channel_compute_difference(channel_name)

Channel write computes difference between previous two values passed to difference method.

add_channel_read_difference(channel_name)

Channel read returns difference between previous two values passed to difference method.

difference(value)

Returns difference between value and value passed in last method call.

register_difference_channel(channel_object)

Automatically calls difference method each time channel_object is read, for example in logger.log().

class PyICe.virtual_instruments.differentiator

Bases: timer, differencer

Virtual differentiator instrument. Differentiate channel is writable and causes computation of first time derivative between value and last written value. Differentiation channels are read-only and return previously computed time derivative, scaled to appropriate time units. Timer channels are read-only and return elapsed time used to compute derivative, scaled to appropriate time units. A readable channel from a different instrument can be registered with this instrument so that any read of that channel causes its value to be differentiated automatically without requiring an explicit call to this instrument’s differentiate method or channel.

add_channel_differentiate(channel_name)

Channel write causes time derivative between write value and previous write value to be computed and stored.

add_channel_differentiation_days(channel_name)

Channel read reports derivative value with time units of days.

add_channel_differentiation_hours(channel_name)

Channel read reports derivative value with time units of hours.

add_channel_differentiation_minutes(channel_name)

Channel read reports derivative value with time units of minutes.

add_channel_differentiation_scale(channel_name, time_div)

Channel read reports derivative value with user supplied time units. time_div is seconds per user-unit, eg 60 for minutes.

add_channel_differentiation_seconds(channel_name)

Channel read reports derivative value with time units of seconds.

differentiate(value)

Scale value by elapsed time and store to accumulator. Should typically be used through integrate channel above.

read_delegated_channel_list(channels)

private

register_derivative_channel(channel_object)

Automatically calls difference method each time channel_object is read, for example in logger.log().

class PyICe.virtual_instruments.digital_analog_io(domain_channel=None, verbose=False)

Bases: instrument

Wraps an analog output PyICe channel with a digital interface. domain_channel is the PyICe channel for the logic supply of the digital input we’re talking to, e.g. master[‘vin_supply’] or master[‘dvcc_supply’].

add_channel_digital_input(channel_name, analog_input_channel, vil_ratio=0.3, vih_ratio=0.7, hys_enable=0, hys_absolute=0)

add a mapping from analog channel to boolean, scaled to variable domain supply absolute voltage thresholds are achievable by using a dummy domain supply channel

add_channel_digital_output(channel_name, output_channel, voh_scale=1, voh_offset=0, vol_scale=0, vol_offset=0)

add a mapping from logic states to analog supply optionally track instrument’s domain supply (through callbacks) with non-zero _scale arguments optionally offset from domain supply by absolute amount with _offset arguments absolute min and max write limits can be achieved using output_channel.set_min_write_limit() and output_channel.set_max_write_limit() after channel creation, additional logic states can be accommodated either by add_logic_state() to this channel, or create another digital channel mapping through the same output_channel use a ramp_to domain channel to interleave output channel writes with each step and prevent logic state changes when domain supply changes

add_digital_output_logic_state(digital_output_channel, digital_state, vo_scale, vo_offset)

add an additional logic state to an existing digital output channel, eg 2 for testhook overdrive. vo_scale is a percentage of the domain channel vo_offset is absolute

enable_digital_output_domain_read_callback(digital_output_channel)

This doesn’t work yet. Is it worth implementing?

class PyICe.virtual_instruments.dummy(*args, **kwargs)

Bases: instrument

Doesn’t do anything. Use to replace missing equipment in a testbench, etc.

add_channel(channel_name, *args, **kwargs)

match arguments of other instrument add_channel methods for easy temporary substitution

add_channel_read(channel_name, *args, **kwargs)

Read-only do-nothing channel

add_channel_write(channel_name, *args, **kwargs)

writeable do-nothing channel.

set_add_channel_is_writeable(add_channel_is_writeable=None)
set_random_read(channel_read_returns_random=True)
set_verbose(verbose=True)
class PyICe.virtual_instruments.dummy_quantum_twin(name=None)

Bases: instrument

add_channel(live_channel, skip_read=False, cached_value=None)

Make a new dummy chanel, entangle it with the live one, and add it to this instrument. Original live channel unchanged except for added callbacks.

class PyICe.virtual_instruments.dummy_read(*args, **kwargs)

Bases: dummy

Dummy instrument with add_channel method defaulted to read-only.

class PyICe.virtual_instruments.dummy_write(*args, **kwargs)

Bases: dummy

Dummy instrument with add_channel method defaulted to writeable.

class PyICe.virtual_instruments.expect(verbose_pass, err_msg_prefix=None, pass_msg_prefix=None)

Bases: instrument

Virtual instrument to check that reading is within specified tolerance of expected result.

add_channel_enable(channel_name, expect_channel)

Enabled/disable expect cheking of expect_channel after creation.

add_channel_expect_abs(channel_name, slave_read_channel, tolerance, en_immediate, en_assertion)

Check that value read from slave_read_channel is within <write_value> +/- tolerance if en_immediate, a write to this channel triggers a read of slave_read_channel and the compare operation otherwise, the compare operation is executed automatically each time slave_read_channel is read. if en_assertion, a failed compare operation raises an ExpectException

add_channel_expect_exact(channel_name, slave_read_channel, en_immediate, en_assertion)

Check that value read from slave_read_channel is equal to <write_value> slave_read_channel must be an integer channel for an exact comparison to make sense. if en_immediate, a write to this channel triggers a read of slave_read_channel and the compare operation otherwise, the compare operation is executed automatically each time slave_read_channel is read. if en_assertion, a failed compare operation raises an ExpectException

add_channel_expect_pct(channel_name, slave_read_channel, tolerance, en_immediate, en_assertion)

Check that value read from slave_read_channel is within <write_value> * (1 +/- tolerance) if en_immediate, a write to this channel triggers a read of slave_read_channel and the compare operation otherwise, the compare operation is executed automatically each time slave_read_channel is read. if en_assertion, a failed compare operation raises an ExpectException

add_channel_tolerance(channel_name, expect_channel)

Modify expect tolerance of expect_channel after creation. Also logs tolerance with results (with pct/abs ambiguity).

check_abs(measured, expect, tolerance, en_assertion, name=None)

Channel-independent absolute/additive check method. Configurable to either emit warning message or raise ExpectException when expectation is not met.

check_exact(measured, expect, en_assertion, name=None)

Channel-independent exact-value check method. Configurable to either emit warning message or raise ExpectException when expectation is not met.

check_pct(measured, expect, tolerance, en_assertion, name=None)

Channel-independent percentage/multiplicative check method. Configurable to either emit warning message or raise ExpectException when expectation is not met.

classmethod compare_abs(measured, expect, tolerance)

check that measured is within expect +/- tolerance

static compare_abs_not_above(measured, expect, tolerance)

check that measured is below (expect + tolerance)

static compare_abs_not_below(measured, expect, tolerance)

check that measured is above (expect - tolerance)

static compare_exact(measured, expect)

check that measured is equal to expect

classmethod compare_lenient(measured, expect, pct_tolerance, abs_tolerance)

check that either absolute tolerance or percentage tolerance is met

classmethod compare_pct(measured, expect, tolerance)

check that measured is within expect * (1 +/- tolerance)

static compare_pct_not_above(measured, expect, tolerance)

check that measured is below expect * (1 + tolerance)

static compare_pct_not_below(measured, expect, tolerance)

check that measured is above expect * (1 - tolerance)

classmethod compare_strict(measured, expect, pct_tolerance, abs_tolerance)

check that both absolute tolerance and percentage tolerance is met

class PyICe.virtual_instruments.instrument_humanoid(notification_function=None)

Bases: instrument, delegator

Notification helper to put human control of a manual instrument into an otherwise automated measurement.

add_channel_notification_enable(channel_name)

Hook to temporarily suspend notifications, ex for initial setup.

add_channel_read(channel_name, integer_size=None)

add new channel named channel_name. Reads from channel_name will send a notification using notification_function and will prompt for input. Useful for including manual measurement instruments in an otherwise automated setup.

add_channel_write(channel_name)

add new channel named channel_name. Writes to channel_name will send a notification using notification_function and will block until the user acknowledges (in the terminal) that they have intervened as appropriate. Useful for including manual forcing instruments in an otherwise automated setup. To set delay after changing channel, use set_write_delay() method of returned channel.

add_notification_function(notification_function)

Add additional notification function to instrument. Ex email and SMS. Notification will be sent to notification_function when a write occurs to any channel in this instrument. The function should take a single string argument and deliver it to the user as appropriate (sms, email, etc). Hint: Use a lambda function to include a subject line in the email: from PyICe.lab_utils.communications import email myemail = email(destination=’myemail@mycompany.com’) notification_function=lambda msg: myemail.send(msg,subject=”LTC lab requires attention!”)

read_delegated_channel_list(channels)

private

set_notification_enable(enabled)

non-channel hook to enable/disable notifications

set_write_block_channel(ch)

wait for channel value to toggle high then low before proceeding

set_write_block_function(fn=None)

replace input() method with alternative way to proceed. IE email or button press

class PyICe.virtual_instruments.integrator(init=0)

Bases: accumulator, timer

Virtual integrator instrument. Integrate channel is writable and accumulates value to internally stored total, multiplied by elapsed time since last integrate channel write. Integration channels are read only and return integration total, scaled to appropriate time units. Timer channels are read-only and return elapsed time used to compute time time differential, scaled to appropriate time units. A readable channel from a different instrument can be registered with this instrument so that any read of that channel causes its value to be integrated automatically without requiring an explicit call to this instrument’s integrate method or channel. All channels operate from a common timebase.

add_channel_integrate(channel_name)

Writing to this channel causes written value to be added to accumulator scaled by elapsed time since last write.

add_channel_integration_days(channel_name)

Channel read reports integration value with time units of days.

add_channel_integration_hours(channel_name)

Channel read reports integration value with time units of hours.

add_channel_integration_minutes(channel_name)

Channel read reports integration value with time units of minutes.

add_channel_integration_scale(channel_name, time_div)

Channel read reports integration value with user supplied time units. time_div is seconds per user-unit, eg 60 for minutes.

add_channel_integration_seconds(channel_name)

Channel read reports integration value with time units of seconds.

integrate(value)

Scale value by elapsed time and store to accumulator. Should typically be used through integrate channel above.

read_delegated_channel_list(channels)

private

register_integrand_channel(channel_object)

Automatically calls integrate method each time channel_object is read, for example in logger.log().

class PyICe.virtual_instruments.leakage_nuller(leakage_measurement_channel, leakage_forcing_channel, voltage_measurement_channel, minimum_output, maximum_output, voltage_abstol, current_abstol, verbose=False)

Bases: instrument

add_channel_null(channel_name, auto_null=False)
measure(estimated_voltage)
null()
class PyICe.virtual_instruments.peak_finder(input_channel, output_channel, reltol)

Bases: instrument

virtual instrument that finds the peak of one channel given a second channel as an input. The function is assumed to be unimodal. The channels used with this instrument may want to be virtual instruments. For example the output channel could be the computation of efficiency from several other channels. The peak is found by recursively performing a ternary search.

add_channel_abscissa(channel_name, auto_find=False)

The value of the input variable at which the peak occurred.

add_channel_peak(channel_name)

The peak value found if the search was successful

add_channel_successful(channel_name, auto_find=False)

Indicates whether or not the search was successful or failed due to lost peak before reltol. Try increasing reltol upon return of False

find(searchstart, searchstop)
class PyICe.virtual_instruments.ramp_to(verbose=False)

Bases: instrument

Virtual instrument that changes channel setting incrementally. Useful to minimize impact of overshoot when trying to use power supply as a precision voltage source. This is a crutch. A better option would be to use an SMU if available.

add_channel_binary(channel_name, forcing_channel, abstol=0.001, max_step=None)

Writes binarily decreasing magnitude steps to forcing_channel until within abstol of final voltage. If specified, max_step will bound the step upper magnitude. Use forcing_channel.set_write_delay(seconds) to control ramp rate.

add_channel_linear(channel_name, forcing_channel, step_size=0.01)

Writes constant steps of size step_size (linear_ramp) to forcing_channel until within abstol of final voltage. Use forcing_channel.set_write_delay(seconds) to control ramp rate.

add_channel_overshoot(channel_name, forcing_channel, abstol, estimated_overshoot)

Writes steps to forcing channel_such that peak overshoot magnitude never exceeds written value by more than abstol. estimated_overshoot is specified as a fraction of setting change (peak = final_value + (final_value - previous_value)*estimated_overshoot). For example, to model 10% overshoot (5V to 6V transition hits peak 6.1V), set estimated_overshoot=0.1.

class PyICe.virtual_instruments.servo(fb_channel, output_channel, minimum, maximum, abstol, reltol=0.001, verbose=False, abort_on_sat=True, max_tries=10, except_on_fail=True)

Bases: instrument

add_channel_target(channel_name)

Channel write causes output_channel to servo to new target value.

check_enpoints()
reconfigure(minimum=None, maximum=None, abstol=None, reltol=None)
servo(target=None)

Servo fb_channel to target by varying output_channel. If target is omitted, previous target is maintained.

servo_check(readback=None)

Returns True if servo is within abstol or reltol tolerances. Returns False if servo failed to converge within alotted number of tries.

Bases: instrument

Servo virtual insturment based on thinly wrapped threshold finder. Servo forces channel to specified value within abstol/reltol tolerance by manipulating other channel.

add_channel_results(channel_name)
add_channel_target(channel_name, auto_find=True)

servo target value (setpoint)

add_channels(channel_name, auto_find=True)
find(value)
class PyICe.virtual_instruments.servo_group(name)

Bases: object

This is a group of servos. It will servo each servo in that group until all are in regulation or up to servo_group.tries times

add_servo(servo_inst)

Add a servo virtual instrument to the servo_group

servo()

run each servo in turn until all are in regulation.

class PyICe.virtual_instruments.simple_servo(fb_channel, output_channel, minimum, maximum, reltol=0.001, abstol=None, verbose=False, max_tries=10, step_method='BINARY')

Bases: instrument

Alternae servo instrument, which makes no assumptions about gain or linearity. Binary and geometric have monotonicity constraints. Linear searches should fine an answer eventually, without a monotonicity constraint

add_channel_target(channel_name)

Channel write causes output_channel to servo to new target value.

is_in_spec(target, setting)
search_direction_override(**kwargs)

Use extra (multivariate or more complex) logic to control servo direction in the face of non-monotonic behavior For example, current measurement too low because too much current caused compliance/dropout problem with servo’d load, measurable though compliance voltage waveform, current limit status bit, etc. return None to allow loop decision to stand return True to force an upward search return False to foece a downward search

This dummy method doesn’t alter behavior, but can be replaced with inheritance or the set_search_direction_override_fn method to point to something with more smarts. Should accept **kwargs dict argument containing servo state information

servo(target)
set_maximum(value)
set_minimum(value)
set_search_direction_override_fn(fn)
class PyICe.virtual_instruments.smart_battery_emulator(voltage_channel_name, current_channel_name, voltage_interval, current_interval, verbose=False)

Bases: instrument

add_channel_current_interval(channel_name)

adds a channel that can change the update interval of the smart battery current

add_channel_voltage_interval(channel_name)

adds a channel that can change the update interval of the smart battery voltage

stop_all()

Kills all threaded channels, can’t be restarted.

class PyICe.virtual_instruments.threshold_finder(comparator_input_force_channel, comparator_output_sense_channel, minimum, maximum, abstol, comparator_input_sense_channel=None, forcing_overshoot=0, output_threshold=None, verbose=False)

Bases: instrument, delegator

virtual instrument Does not automatically find threshold unless auto_find is enabled from add_channel. Otherwise, you must call threshold_finder.find(), or .find_linear()

The channels used with this instrument may want to be virtual instruments. For example the comparator_input_channel_force could be used to clear a latched output before a new value is set, or the comparator_output_sense_channel could interpret complex comparator outputs that are not direct measurements.

Note that these search algorithms are sensitive to absolute repeatability. The DUT must not return different output values for the same forced values (within abstol and noise limits). If it does, the search will permanently take a wrong turn and fail.

If the search algorithm is failing, check the properties of the input forcing channel and the DUT. Specifically:
  1. Make sure the forcing channel doesn’t overshoot.
    1. If it does, update the forcing_overshoot parameter to a larger number and consider using a less aggressive search algorithm.

    2. Also consider a better forcing instrument with negligible overshoot (SMU, etc)

  2. Make sure the forcing instrument has settled before the DUT output measurement is taken.
    1. Consider [comparator_input_force_channel].set_write_delay(some_time)

    2. Also consider a better forcing instrument with rapid settling (SMU, etc)

  3. Make sure the DUT has settled after the forcing input channel has settled.
    1. This time can be quite long with nearly zero overdrive (forced input very close to true threshold)

    2. This time tents to infinity with zero overdrive, but we are only guaranteeing results to within abstol

    3. Therefore, the DUT should have sufficient time to settle with |abstol| overdrive applied after forcing channel has settled.

    4. Add this worst case DUT settling time to the forcing channel delay above.

add_channel_abstol(channel_name)

Maximum two-sided uncertainty range (window width) for binary search, or step size for linear search. Relative to comparator_input_force_channel.

add_channel_algorithm(channel_name)

Search method used to determine threshold.

add_channel_all(channel_name, auto_find=False)

shortcut method adds the following channels: threshold (Average of rising and falling thresholds. Relative to comparator_input_sense_channel.) rising threshold (Average of measurements at low and high endpoints of rising threshold uncertainty window. Relative to comparator_input_sense_channel.) falling threshold (Average of measurements at low and high endpoints of falling threshold uncertainty window. Relative to comparator_input_sense_channel.) tries (Number of binary search steps required to reduce uncertainty window to within abstol, or number of abstol-sized steps required to find threshold with linear search.) hysteresis (Difference between rising and falling thresholds. Relative to comparator_input_sense_channel.) abstol (Maximum two-sided uncertainty range (window width) for binary search, or step size for linear search. Relative to comparator_input_force_channel.) rising uncertainty (Achieved one-sided additive rising threshold uncertainty range for binary or linear search. Relative to comparator_input_sense_channel.) falling uncertainty (Achieved one-sided additive falling threshold uncertainty range for binary or linear search. Relative to comparator_input_sense_channel.) rising relative uncertainty (Achieved one-sided multiplicative rising threshold uncertainty range for binary or linear search. Relative to comparator_input_sense_channel.) falling relative uncertainty (Achieved one-sided multiplicative falling threshold uncertainty range for binary or linear search. Relative to comparator_input_sense_channel.) forced rising threshold (Average of low and high forced endpoints of rising threshold uncertainty window. Relative to comparator_input_force_channel.) forced falling threshold (Average of low and high forced endpoints of falling threshold uncertainty window. Relative to comparator_input_force_channel.) output_threshold (Calculated or specified digitization threshold for comparator_output_sense_channel.)

if auto_find is ‘linear’, automatically call find_linear() when channel is read. if auto_find is ‘geometric’, automatically call find_geometric() when channel is read. if auto_find is any other true value, automatically call find() when channel is read.

add_channel_falling(channel_name)

Average of measurements at low and high endpoints of falling threshold uncertainty window. Relative to comparator_input_sense_channel.

add_channel_forced_falling(channel_name)

Average of low and high forced endpoints of falling threshold uncertainty window. Relative to comparator_input_force_channel.

add_channel_forced_rising(channel_name)

Average of low and high forced endpoints of rising threshold uncertainty window. Relative to comparator_input_force_channel.

add_channel_hysteresis(channel_name)

Difference between rising and falling thresholds. Relative to comparator_input_sense_channel.

add_channel_output_threshold(channel_name)

Computed digitization threshold for comparator_output_sense_channel.

add_channel_output_threshold_setpoint(channel_name)

Digitization threshold setpoint for comparator_output_sense_channel. Caution: a reconfigure() command outsize the channel framework will un-sync this parameter.

add_channel_relative_uncertainty(channel_name)

Single sided relative measured threshold uncertainty at termination of search. i.e threshold_rising * (1 - relative_uncertainty_rising) < {true rising threshold} < threshold_rising * (1 + relative_uncertainty_rising) and

threshold_falling * (1 - relative_uncertainty_falling) < {true falling threshold} < threshold_falling * (1 + relative_uncertainty_falling)

With comparator_input_sense_channel defined, uncertainty will be relative to measured rather than forced inputs and may be scaled differently than forcing (abstol) units.

add_channel_rising(channel_name)

Average of measurements at low and high endpoints of rising threshold uncertainty window. Relative to comparator_input_sense_channel.

add_channel_threshold(channel_name, auto_find=False)

Average of rising and falling thresholds found by last call to find() method. Relative to comparator_input_sense_channel. if auto_find is ‘linear’, automatically call find_linear() when channel is read. if auto_find is ‘geometric’, automatically call find_geometric() when channel is read. if auto_find is any other true value, automatically call find() when channel is read.

add_channel_tries(channel_name)

Number of binary search steps required to reduce uncertainty window to within abstol, or number of abstol-sized steps required to find threshold with linear search.

add_channel_uncertainty(channel_name)

Single sided measured threshold uncertainty at termination of search. i.e (threshold_rising - uncertainty_rising) < {true rising threshold} < (threshold_rising + uncertainty_rising) and

(threshold_falling - uncertainty_falling) < {true falling threshold} < (threshold_falling + uncertainty_falling).

For binary search with comparator_input_sense_channel=None, will be between 0.5*abstol and 0.25*abstol. For linear sweep with comparator_input_sense_channel=None, will be 0.5*abstol.

With comparator_input_sense_channel defined, uncertainty will be relative to measured rather than forced inputs and may be scaled differently than forcing (abstol) units.

debug_print(msg)
find(cautious=False)

Hysteresis-aware double binary search. Returns dictionary of results. if cautious, perform extra measurement at each step to ensure hysteresis flips and search region has not been corrupted.

find_geometric(decades=None)

Perform repeated linear searches for rising and falling thresholds with 10x increase in resolution each iteration. Final resolution is abstol Optionally specify decades argument to control how many searches are performed. Defaults to as many as possible for given min/max range and abstol. No steps are ever made toward the threshold with magnitude larger than current search’s resolution in case of overshoot.

find_hybrid(linear_backtrack=None)

Perform course binary search, then approach rising and falling thresholds from correct direction with linear search. Both binary and linear searches will be performed to abstol forcing tolerance. The linear search will be started linear_backtrack distance away from expected threshold, with default of 5 * reltol. Each of the two linear sweeps will take approximately (linear_backtrack / reltol) steps toward threshold. Steps toward threshold are of max magnitude max_step.

find_linear()

Hysteresis aware linear sweep. Returns dictionary of results

find_no_hysteresis(cautious=False)

Hysteresis-unaware single binary search. Returns dictionary of results. If cautious, perform extra measurment at each step to ensure that the threashold is still bounded by the current search interval.

measure_input(input_sense_channel)

Measure input sense (Kelvin) channel manually after completion of search algorithm. This may be somewhat less accurate than measuring sense channel during search. It exposes possibly non-ideal hysteresis or gain/offset drift of the forcing instrument by uncorrelating measurements in time.

Typically used with comparator_input_sense_channel=None to speed up search at each point. Updates and returns internal results dictionary.

read_delegated_channel_list(channels)

private

reconfigure(comparator_input_force_channel, comparator_output_sense_channel, comparator_input_sense_channel, output_threshold=None, minimum=None, maximum=None, abstol=None, forcing_overshoot=None)

Reconfigure channel settings to use a single threshold finder instrument with multiplexed DUT channels. Required arguments: comparator_input_force_channel - DUT comparator input forcing channel object. comparator_output_sense_channel - DUT comparator output measurement channel object. comparator_input_sense_channel - optionally specify a channel object to read back actual (Kelvin) input to DUT from comparator_input_force_channel. Set to None to disable.

Optional argument (set to automatic if unspecified): output_threshold - optional digitization level threshold for comparator_output_sense_channel. If unspecified, will be calculated from mean of comparator_output_sense_channel reading with comparator_input_channel_force set to minimum and maximum.

Optional arguments (unchanged if unspecified): minimum - minimum forced input to the DUT comparator via comparator_input_force_channel. maximum - maximum forced input to the DUT comparator via comparator_input_force_channel. abstol - resolution of search. Relative to comparator_input_channel_force, not comparator_input_sense_channel.

test_repeatability(linear_backtrack=None, decades=None)
class PyICe.virtual_instruments.timer(category='Timer Virtual Instrument')

Bases: instrument, delegator

Virtual timer instrument. All channels are read only and return time since either last read or first read, scaled to appropriate time units. All channels operate from a common timebase.

add_channel_delta_days(channel_name)

Channel read reports elapsed time since last read with units of days.

add_channel_delta_hours(channel_name)

Channel read reports elapsed time since last read with units of hours.

add_channel_delta_minutes(channel_name)

Channel read reports elapsed time since last read with units of minutes.

add_channel_delta_scale(channel_name, time_div)

Channel read reports elapsed time since last read with user supplied time units. time_div is seconds per user-unit, eg 60 for minutes.

add_channel_delta_seconds(channel_name)

Channel read reports elapsed time since last read with units of seconds.

add_channel_frequency_hz(channel_name)

Channel read reports read frequency in Hz.

add_channel_frequency_scale(channel_name, time_div)

Channel read reports read frequency with user supplied time units. time_div is seconds per user-unit, eg 60 for RPM.

add_channel_total_days(channel_name)

Channel read reports elapsed time since first read with units of days.

add_channel_total_hours(channel_name)

Channel read reports elapsed time since first read with units of hours.

add_channel_total_minutes(channel_name)

Channel read reports elapsed time since first read with units of minutes.

add_channel_total_scale(channel_name, time_div)

Channel read reports elapsed time since first read with user supplied time units. time_div is seconds per user-unit, eg 60 for minutes.

add_channel_total_seconds(channel_name)

Channel read reports elapsed time since first read with units of seconds.

pause_timer()

pause timer . Call resume_timer() to continue counting.

read_delegated_channel_list(channels)

private

reset_timer()

Resets timer to 0. Use with caution outside channel framework.

resume_timer()

resume timer . Call pause_timer() to stop counting again. Can also call resume_timer() at the beginning of time to start the timer.

stop_and_reset_timer()

Halts and resets timer to 0. Timer will begin running after first read, same behavior as after timer object instantiation. Use with caution outside channel framework.

class PyICe.virtual_instruments.vector_to_scalar_converter

Bases: instrument

reduce rank of channel data from iterable vector data to scalar data using arbitrary reduction function (average, sum, std. dev, etc)

add_channel(channel_name, vector_data_channel, reduction_function)

vector reduction channel that operates by directly reading vector_data_channel. Reading this channel will cause vector_data_channel to be read, and will cause vector_data_channel to be read twice if both vector_data_channel and this virtual channel are in the read list.

add_channel_callback(channel_name, vector_data_channel, reduction_function)

vector reduction channel that operates by a callback whenever vector_data_channel is read. Reading this channel won’t cause vector_data_channel to be read, nor will this channel’s value be updated.

classmethod mean(sequence)

arithmetic mean of sequence

classmethod pstdev(sequence)

population std deviation

classmethod rms(sequence)

RMS (root mean square). To instead subtract sample mean, use pstdev

classmethod stdev(sequence)

sample std deviation

static sum(sequence)

arithmetic sum

PyICe.visa_wrappers module

VISA Emulation Layer

Interface wrappers to use various interfaces as if they were VISA resources without requiring an installed VISA library. Facilitates seamless transition between physical inrefaces and operating systems.

PyICe.visa_wrappers.byteify(s)
PyICe.visa_wrappers.strify(bs)
exception PyICe.visa_wrappers.visaWrapperException

Bases: Exception

class PyICe.visa_wrappers.visa_interface(address, timeout=5)

Bases: visa_wrapper

agilent visa strips trailing termination character, but NI VISA seems to leave them in response.

ask(message)
ask_for_values(message)
ask_for_values_binary(message, format_str='B', byte_order='=', terminationCharacter='')

Follows Definite Length Arbitrary Block format ie ASCII header ‘#<heder_bytes_following><data_bytes_following><data0>…<dataN> eg #40003<byte0><byte1><byte2><byte3> format_str and byte_order are passed to struct library for to set word boundaries for unpacking and conversion to numeric types https://docs.python.org/2/library/struct.html#format-strings

clear()
close()
flush(buffer)
read()
read_raw()
read_values()
property term_chars
property timeout
trigger()
write(message)
class PyICe.visa_wrappers.visa_wrapper

Bases: object

ask(message)
ask_for_values(message)
ask_for_values_binary(message, format_str='B', byte_order='=', terminationCharacter='')

Follows Definite Length Arbitrary Block format ie ASCII header ‘#<heder_bytes_following><data_bytes_following><data0>…<dataN> eg #40003<byte0><byte1><byte2><byte3> format_str and byte_order are passed to struct library for to set word boundaries for unpacking and conversion to numeric types https://docs.python.org/2/library/struct.html#format-strings

clear()
clear_errors()
close()
read()
read_raw()
read_values()
read_values_binary(format_str='=B', byte_order='=', terminationCharacter='')

Follows Definite Length Arbitrary Block format ie ASCII header ‘#<heder_bytes_following><data_bytes_following><data0>…<dataN> eg #40003<byte0><byte1><byte2><byte3> format_str and byte_order are passed to struct library for to set word boundaries for unpacking and conversion to numeric types https://docs.python.org/2/library/struct.html#format-strings

resync()

flush buffers to resync after communication fault - usb-serial problem

property term_chars
property timeout
trigger()
write(message)
class PyICe.visa_wrappers.visa_wrapper_serial(address_or_serial_obj, timeout=5, baudrate=9600, **kwargs)

Bases: visa_wrapper

close()
flush()
get_serial_port()

Returns the underlying serial port object.

read()
read_raw()
read_values()
read_values_binary(format_str='B', byte_order='=', terminationCharacter='')

Follows Definite Length Arbitrary Block format ie ASCII header ‘#<heder_bytes_following><data_bytes_following><data0>…<dataN> eg #40003<byte0><byte1><byte2><byte3>

format_str is passed to struct library for to set word boundaries for unpacking and conversion to numeric types https://docs.python.org/2/library/struct.html#format-strings https://en.wikipedia.org/wiki/IEEE_754-1985 ‘B’: default unsigned single byte ‘b’: signed single byte

‘H’: unsigned short 2-byte integer ‘h’: signed short 2-byte integer

‘I’: unsigned 4-byte integer ‘i’: signed 4-byte integer

‘Q’: unsigned long long 8-byte integer ‘q’: signed long long 8-byte integer

‘f’: 4-byte IEEE_754-1985 float ‘d’: 8-byte IEEE_754-1985 double precision float

‘<n>s’: An <n>-byte long string

byte_order sets endianness: ‘=’: native ‘<’: little-endian (LSByte first) ‘>’: big-endian (MSByte first)

readline()
resync()

flush buffers to resync after communication fault - usb-serial problem

property timeout
write(message)
write_raw(message)
class PyICe.visa_wrappers.visa_wrapper_tcp(ip_address, port, timeout=5, **kwargs)

Bases: visa_wrapper_serial

resync()

flush buffers to resync after communication fault - usb-serial problem

property timeout
class PyICe.visa_wrappers.visa_wrapper_telnet(ip_address, port, timeout=5)

Bases: visa_wrapper_serial

readline()
resync()

flush buffers to resync after communication fault - usb-serial problem

property timeout
class PyICe.visa_wrappers.visa_wrapper_usbtmc(address, timeout=5)

Bases: visa_wrapper

ask(message)
ask_for_values(message)
clear()
close()
open()
read()
read_raw()
read_values()
resync()

flush buffers to resync after communication fault - usb-serial problem

property timeout
trigger()
write(message)
class PyICe.visa_wrappers.visa_wrapper_vxi11(address, timeout=5)

Bases: visa_wrapper

ask(message)
ask_for_values(message)
clear()
close()
open()
read()
read_raw()
read_values()
resync()

flush buffers to resync after communication fault - usb-serial problem

property timeout
trigger()
write(message)

Module contents