PyICe package
Subpackages
- PyICe.data_utils package
- Submodules
- PyICe.data_utils.EMI_char_levels module
- PyICe.data_utils.create_user_files module
- PyICe.data_utils.oscilloscope_waveform_dump module
- PyICe.data_utils.pds_utils module
- PyICe.data_utils.stdf_structure_tracer module
- PyICe.data_utils.stdf_utils module
- PyICe.data_utils.touchstone_utils module
- PyICe.data_utils.units_parser module
- PyICe.data_utils.wave_analysis module
waveform
waveform.amplitude()
waveform.average_in()
waveform.average_out()
waveform.dump_data()
waveform.fall_time()
waveform.find_first_falling_edge()
waveform.find_first_rising_edge()
waveform.find_grt_than_or_equal_to()
waveform.find_less_than_or_equal_to()
waveform.overshoot()
waveform.plot()
waveform.read_xdata()
waveform.read_ydata()
waveform.rise_time()
waveform.settling_time()
waveform.settling_time_from_max_deviation()
waveform.settling_time_outside_limit()
waveform.slew_rate()
waveform.sw_fall_time()
waveform.sw_nol_fall()
waveform.sw_nol_rise()
waveform.sw_rise_time()
waveform.trigger()
waveform.trigger_10_90()
waveform.trigger_index()
waveform.trigger_level()
waveform.trigger_polarity()
waveform.trigger_sigma()
waveform.trigger_value()
waveform.undershoot()
- Module contents
- PyICe.deps package
- PyICe.instruments package
- Submodules
- PyICe.instruments.AD5272 module
- PyICe.instruments.AD5667R module
- PyICe.instruments.AD5693R module
- PyICe.instruments.ADT7410 module
- PyICe.instruments.BR24H64 module
- PyICe.instruments.CAT5140 module
- PyICe.instruments.ENA module
- PyICe.instruments.Franken_oven module
- PyICe.instruments.PCF8574 module
- PyICe.instruments.PSA module
- PyICe.instruments.TMP117 module
- PyICe.instruments.TestEquity_115 module
- PyICe.instruments.a3497x_instruments module
- PyICe.instruments.agilent_3034a module
- PyICe.instruments.agilent_33220a module
- PyICe.instruments.agilent_34401a module
- PyICe.instruments.agilent_3458a module
- PyICe.instruments.agilent_35670a module
- PyICe.instruments.autonicstk module
- PyICe.instruments.bk8500 module
- PyICe.instruments.bk8600 module
- PyICe.instruments.daq970a_instruments module
- PyICe.instruments.delta_9039 module
- PyICe.instruments.fluke_8845 module
- PyICe.instruments.hameg_4040 module
- PyICe.instruments.htx9000 module
- PyICe.instruments.htx9001 module
- PyICe.instruments.htx9001a module
- PyICe.instruments.htx9011 module
- PyICe.instruments.htx9016 module
- PyICe.instruments.hypertronix_powermux module
- PyICe.instruments.keysight_u2300a module
- PyICe.instruments.manual_oven module
- PyICe.instruments.modbus_register module
- PyICe.instruments.modbus_relay module
- PyICe.instruments.ni_pxi5413 module
- PyICe.instruments.oscilloscope module
- PyICe.instruments.pyice_arduino_tool module
- PyICe.instruments.reaylabs_rl1000 module
- PyICe.instruments.relay module
- PyICe.instruments.rigol_DG800 module
- PyICe.instruments.saleae module
- PyICe.instruments.siglent_SDG1000X module
- PyICe.instruments.smu module
- PyICe.instruments.spi_dongle module
- PyICe.instruments.sun_ec0x module
- PyICe.instruments.sun_ec1x module
- PyICe.instruments.sun_ecxx module
- PyICe.instruments.tektronix_afg3022 module
- PyICe.instruments.tektronix_mso4104b module
- PyICe.instruments.telemetrix_io module
- PyICe.instruments.temperature_chamber module
- Module contents
- PyICe.refid_modules package
- Submodules
- PyICe.refid_modules.bench_base module
- PyICe.refid_modules.bench_identifier module
- PyICe.refid_modules.p4_traceability module
- PyICe.refid_modules.stdf_utils module
- PyICe.refid_modules.temptroller module
- PyICe.refid_modules.test_archive module
- PyICe.refid_modules.test_module module
isnan()
multitest_module
multitest_unit
multitest_unit.compile_test_results()
multitest_unit.debug_mode()
multitest_unit.get_correlation_data()
multitest_unit.get_correlation_data_scalar()
multitest_unit.get_die_traceability_hash_table()
multitest_unit.get_name()
multitest_unit.get_revid()
multitest_unit.get_test_limits()
multitest_unit.get_variant_id()
multitest_unit.plot()
multitest_unit.register_tests()
regressionException
test_module
test_module.abort_regression()
test_module.collect()
test_module.configure_bench()
test_module.copy_table()
test_module.crash_info()
test_module.debug_mode()
test_module.export_table_xlsx()
test_module.get_db()
test_module.get_db_table_name()
test_module.get_import_str()
test_module.get_lab_bench()
test_module.get_logger()
test_module.get_max_test_temp()
test_module.get_min_test_temp()
test_module.get_name()
test_module.hook_functions()
test_module.in_range()
test_module.is_crashed()
test_module.plot()
test_module.plot_from_table()
test_module.reconfigure()
test_module.register_db_index()
test_module.register_plugin()
test_module.run()
test_module.run_repeatability()
test_module.set_max_test_temp()
test_module.set_min_test_temp()
test_module.setup()
test_module.teardown()
test_module.temp_is_included()
- PyICe.refid_modules.test_results module
- Module contents
- PyICe.xml_registers package
- Subpackages
- PyICe.xml_registers.EXAMPLE package
- PyICe.xml_registers.asm_header package
- PyICe.xml_registers.c_api package
- PyICe.xml_registers.cpp_ets_api package
- PyICe.xml_registers.datasheet_indesign package
- PyICe.xml_registers.doc package
- PyICe.xml_registers.micro16c package
- PyICe.xml_registers.python_api package
- PyICe.xml_registers.register_lint package
- PyICe.xml_registers.reorder_bitfields package
- PyICe.xml_registers.sanitize package
- PyICe.xml_registers.variants package
- PyICe.xml_registers.vb_api package
- PyICe.xml_registers.verilog_header package
- PyICe.xml_registers.verilog_mem_map package
- PyICe.xml_registers.verilog_rtl package
- Module contents
- 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:
plot
Page
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:
add_plot()
create_pdf()
create_svg()
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:
create_pdf(“LTCXXXX_Page1”)
create_svg(“LTCXXXX_Page1”)
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:
Creates a zip file.
Creates a disposable page.
Adds one plot that is found on your Page.
Creates an SVG file of the disposable page and adds it to the zip file.
Repeats for each plot on your Page. The disposable Page evaporates.
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:
kit_datasheet(“LTCXXXX_Page1”)
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:
It’s possible to choke the input parsee of test equipment if it has limited input buffer size for the command
- 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:
extend instrument class
call the instrument classes __init__ from its __init__
- contain an add_channel (and/or add_channel_XXXXX) methods that:
- create a channel object with a:
name
EITHER a read_function or write_function
call the _add_channel method with that channel as an argument
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.
- 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)
- 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.
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:
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.
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_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_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_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.logo module
- PyICe.logo.display()
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:
- shift_register
abstracts individual bit-fields into integer representing contents of full-length shift register
- 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.
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.
- class PyICe.virtual_instruments.servo_binary_search(fb_channel, output_channel, minimum_output, maximum_output, abstol, output_readback_channel=None, verbose=False)
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:
- Make sure the forcing channel doesn’t overshoot.
If it does, update the forcing_overshoot parameter to a larger number and consider using a less aggressive search algorithm.
Also consider a better forcing instrument with negligible overshoot (SMU, etc)
- Make sure the forcing instrument has settled before the DUT output measurement is taken.
Consider [comparator_input_force_channel].set_write_delay(some_time)
Also consider a better forcing instrument with rapid settling (SMU, etc)
- Make sure the DUT has settled after the forcing input channel has settled.
This time can be quite long with nearly zero overdrive (forced input very close to true threshold)
This time tents to infinity with zero overdrive, but we are only guaranteeing results to within abstol
Therefore, the DUT should have sufficient time to settle with |abstol| overdrive applied after forcing channel has settled.
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)