Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fetch_capture_waveform() fancy wrapper #1096

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2709431
Initial fetch_capture_waveform()
texasaggie97-zz Nov 4, 2019
77db9ae
Set library function to library-only
texasaggie97-zz Nov 4, 2019
f65cd59
Need something to avoid flake8 error
texasaggie97-zz Nov 4, 2019
0b5473e
ivi-dance[-with-a-twist] does not support more than one variable in t…
texasaggie97-zz Nov 4, 2019
c4edad6
Remove all 'codegen-method': 'no' functions
texasaggie97-zz Nov 4, 2019
0ea1cb6
Add support for 'codegen-method': 'library-only'
texasaggie97-zz Nov 4, 2019
2f95ea5
Remove problematic function - will be added back in a later PR
texasaggie97-zz Nov 4, 2019
d19768b
Update generated files - links will go back to not existing when all …
texasaggie97-zz Nov 4, 2019
286b698
Add use_array: True
texasaggie97-zz Nov 4, 2019
bd308c3
Merge branch 'codegen-method-library-only' into bug1076/add_fetch_cap…
texasaggie97-zz Nov 4, 2019
5c39cc2
Update fancy_fetch_capture_waveform.py.mako
texasaggie97-zz Nov 6, 2019
3b4315a
Add enum so we can use it
texasaggie97-zz Nov 6, 2019
878cf89
Update fancy_fetch_capture_waveform.py.mako
texasaggie97-zz Nov 6, 2019
2029662
Update generated files
texasaggie97-zz Nov 6, 2019
0f55cbe
Update CHANGELOG.md
texasaggie97-zz Nov 6, 2019
151b667
Merge branch 'master' into bug1076/add_fetch_capture_waveform_u32
texasaggie97-zz Nov 6, 2019
ebb4474
Fix name and order
texasaggie97-zz Nov 6, 2019
36443c8
Convert timeout from datetime before passing to private function
texasaggie97-zz Nov 6, 2019
9e29d92
Rename namedtuple and reorder items
texasaggie97-zz Nov 6, 2019
ea2a318
Add documentation
texasaggie97-zz Nov 6, 2019
e275ea7
Remove incorrect documentation
texasaggie97-zz Nov 6, 2019
9ca0d06
Add metadata so that generated documentation will be correct
texasaggie97-zz Nov 6, 2019
c841828
Update generated files
texasaggie97-zz Nov 6, 2019
d342658
Merge branch 'master' into codegen-method-library-only
texasaggie97-zz Nov 7, 2019
a42fdfd
Merge branch 'codegen-method-library-only' into bug1076/add_fetch_cap…
texasaggie97-zz Nov 7, 2019
2250729
Merge branch 'master' into bug1076/add_fetch_capture_waveform_u32
texasaggie97-zz Nov 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ All notable changes to this project will be documented in this file.
* #### Removed
* ### NI-Digital Pattern Driver
* #### Added
* `fetch_capture_waveform()` - returns namedtuple `Waveform(site, data)`
* #### Changed
* Fix get/set properties - [#1062](https://github.com/ni/nimi-python/issues/1062)
* #### Removed
Expand Down
18 changes: 6 additions & 12 deletions docs/nidcpower/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ abort
when you call the :py:meth:`nidcpower.Session.abort` method, the output channels remain
in their current state and continue providing power.

Use the :py:meth:`nidcpower.Session.ConfigureOutputEnabled` method to disable power
Use the :py:meth:`nidcpower.Session.configure_output_enabled` method to disable power
output on a per channel basis. Use the :py:meth:`nidcpower.Session.reset` method to
disable output on all channels.

Expand All @@ -151,8 +151,6 @@ abort



.. note:: One or more of the referenced methods are not in the Python API for this driver.



close
Expand All @@ -165,7 +163,7 @@ close
Closes the session specified in **vi** and deallocates the resources
that NI-DCPower reserves. If power output is enabled when you call this
method, the output channels remain in their existing state and
continue providing power. Use the :py:meth:`nidcpower.Session.ConfigureOutputEnabled`
continue providing power. Use the :py:meth:`nidcpower.Session.configure_output_enabled`
method to disable power output on a per channel basis. Use the
:py:meth:`nidcpower.Session.reset` method to disable power output on all channel(s).

Expand All @@ -176,8 +174,6 @@ close



.. note:: One or more of the referenced methods are not in the Python API for this driver.

.. note:: This method is not needed when using the session context manager


Expand Down Expand Up @@ -987,15 +983,15 @@ query_in_compliance
The compliance limit is the current limit when the output method is
set to :py:data:`~nidcpower.OutputFunction.DC_VOLTAGE`. If the output is operating at the
compliance limit, the output reaches the current limit before the
desired voltage level. Refer to the :py:meth:`nidcpower.Session.ConfigureOutputFunction`
method and the :py:meth:`nidcpower.Session.ConfigureCurrentLimit` method for more
desired voltage level. Refer to the :py:meth:`nidcpower.Session.configure_output_function`
method and the :py:meth:`nidcpower.Session.configure_current_limit` method for more
information about output method and current limit, respectively.

The compliance limit is the voltage limit when the output method is
set to :py:data:`~nidcpower.OutputFunction.DC_CURRENT`. If the output is operating at the
compliance limit, the output reaches the voltage limit before the
desired current level. Refer to the :py:meth:`nidcpower.Session.ConfigureOutputFunction`
method and the :py:meth:`nidcpower.Session.ConfigureVoltageLimit` method for more
desired current level. Refer to the :py:meth:`nidcpower.Session.configure_output_function`
method and the :py:meth:`nidcpower.Session.configure_voltage_limit` method for more
information about output method and voltage limit, respectively.

**Related Topics:**
Expand All @@ -1004,8 +1000,6 @@ query_in_compliance



.. note:: One or more of the referenced methods are not in the Python API for this driver.


.. tip:: This method requires repeated capabilities (channels). If called directly on the
nidcpower.Session object, then the method will use all repeated capabilities in the session.
Expand Down
62 changes: 61 additions & 1 deletion docs/nidigital/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,66 @@ export_signal

:type output_terminal: str

fetch_capture_waveform
----------------------

.. py:currentmodule:: nidigital.Session

.. py:method:: fetch_capture_waveform(site_list, waveform_name, samples_to_read, timeout)

Returns a list of named tuples (Waveform) that <FILL IN THE BLANK HERE>

Fields in Waveform:

- **site** (int)
- **data** (array.array of int)
Comment on lines +1571 to +1572
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if named tuple of int/array of int is the best way to return this.
What are all the places in the API in which this type could be used? Can it ever be an input?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in two places:

  1. niDigital_SortSiteResultsViUInt32Waveform - This will NOT be added in Python, since its use is superseded by multi-instrument sessions.
  2. niDigital_WriteSourceWaveformSiteUniqueU32 - This should use the same type as what we use here for fetch_capture_waveform. Tracked here.

I looked at one of the use-cases for fetch_capture_waveform - streaming capture waveform data from h/w test program. It would be ideal for fetch_capture_waveform to accept a buffer and populate that with the waveform data (like fetch_into in niscope).

But the streaming use-case is not common and even then the size is about tens of MBs. If we learn about a use-case where performance is not sufficient, we can add fetch_into later. Usability of streaming with fetch_capture_waveform that returns a dict is not bad:

# Pattern burst is configured to fetch 1024 samples
 num_samples_expected = 16
 samples_per_fetch = 4
 waveforms = collections.defaultdict(list)
 for i in range(num_samples_expected // samples_per_fetch):
     fetched_waveform = multi_instrument_session.fetch_capture_waveform(site_list='', waveform_name='capt_wfm', samples_to_read=samples_per_fetch, timeout=10.0)
     for key in fetched_waveform:
         waveforms[key] += fetched_waveform[key]

So, now the question is whether to use dict or namedtuple..

One drawback for dict is iteration order is not deterministic (at least in Python 3.5). It looks like in 3.6 and later, iteration is ordered. Either way, I think it's better to not guarantee any order, because trying to do that is little tricky:

If method is called with site='' then the order will 0,1,2... with disabled sites skipped.
If method is called with site='3,0,1' (crazy but allowed), then the order will be 3,0,1 with disabled sites skipped.

Given that order depends on input and also can contain gaps, users should not really rely on order. Even if they want to iterate in a particular order, it's not difficult to do that in Python (Everything's easy in Python )

In summary, the recommendation is dict(int, array of unsigned int)






:param site_list:





:type site_list: str
:param waveform_name:





:type waveform_name: str
:param samples_to_read:





:type samples_to_read: int
:param timeout:





:type timeout: float or datetime.timedelta

:rtype: list of Waveform
:return:


List of named tuples with fields:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the order important?
Maybe it would be nicer for clients to return a dictionary of site -> data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See answer above.

TL;DR - dict is better.


- **site** (int)
- **data** (array.array of int)





fetch_history_ram_cycle_information
-----------------------------------

Expand Down Expand Up @@ -2114,7 +2174,7 @@ get_site_results_site_numbers



:type site_result_type: int
:type site_result_type: :py:data:`nidigital.SiteResult`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not appear to be related to this PR.


:rtype: list of int
:return:
Expand Down
13 changes: 13 additions & 0 deletions docs/nidigital/enums.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ Signal



SiteResult
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not appear to be related to this PR.

----------

.. py:class:: SiteResult

.. py:attribute:: SiteResult.PASS_FAIL



.. py:attribute:: SiteResult.CAPTURE_WAVEFORM



TDREndpointTermination
----------------------

Expand Down
20 changes: 5 additions & 15 deletions docs/nidmm/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -515,39 +515,33 @@ configure_thermistor_custom


Specifies the Steinhart-Hart A coefficient for thermistor scaling when
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.ConfigureThermistorType`
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.configure_thermistor_type`
method. The default is 1.0295e-3 (44006).



.. note:: One or more of the referenced methods are not in the Python API for this driver.


:type thermistor_a: float
:param thermistor_b:


Specifies the Steinhart-Hart B coefficient for thermistor scaling when
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.ConfigureThermistorType`
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.configure_thermistor_type`
method. The default is 2.391e-4 (44006).



.. note:: One or more of the referenced methods are not in the Python API for this driver.


:type thermistor_b: float
:param thermistor_c:


Specifies the Steinhart-Hart C coefficient for thermistor scaling when
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.ConfigureThermistorType`
Thermistor Type is set to Custom in the :py:meth:`nidmm.Session.configure_thermistor_type`
method. The default is 1.568e-7 (44006).



.. note:: One or more of the referenced methods are not in the Python API for this driver.


:type thermistor_c: float

Expand Down Expand Up @@ -1498,16 +1492,14 @@ perform_open_cable_comp
measurements for the current capacitance/inductance range, and returns
open cable compensation **Conductance** and **Susceptance** values. You
can use the return values of this method as inputs to
:py:meth:`nidmm.Session.ConfigureOpenCableCompValues`.
:py:meth:`nidmm.Session.configure_open_cable_comp_values`.

This method returns an error if the value of the :py:attr:`nidmm.Session.method`
property is not set to :py:data:`~nidmm.Method.CAPACITANCE` (1005) or
:py:data:`~nidmm.Method.INDUCTANCE` (1006).



.. note:: One or more of the referenced methods are not in the Python API for this driver.



:rtype: tuple (conductance, susceptance)
Expand Down Expand Up @@ -1543,16 +1535,14 @@ perform_short_cable_comp
Performs the short cable compensation measurements for the current
capacitance/inductance range, and returns short cable compensation
**Resistance** and **Reactance** values. You can use the return values
of this method as inputs to :py:meth:`nidmm.Session.ConfigureShortCableCompValues`.
of this method as inputs to :py:meth:`nidmm.Session.configure_short_cable_comp_values`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These does not appear to be related to this PR.


This method returns an error if the value of the :py:attr:`nidmm.Session.method`
property is not set to :py:data:`~nidmm.Method.CAPACITANCE` (1005) or
:py:data:`~nidmm.Method.INDUCTANCE` (1006).



.. note:: One or more of the referenced methods are not in the Python API for this driver.



:rtype: tuple (resistance, reactance)
Expand Down
14 changes: 3 additions & 11 deletions docs/niscope/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -436,15 +436,13 @@ configure_horizontal_timing


The minimum number of points you need in the record for each channel;
call :py:meth:`niscope.Session.ActualRecordLength` to obtain the actual record length
call :py:meth:`niscope.Session.actual_record_length` to obtain the actual record length
used.

Valid Values: Greater than 1; limited by available memory



.. note:: One or more of the referenced methods are not in the Python API for this driver.


:type min_num_pts: int
:param ref_position:
Expand Down Expand Up @@ -2343,7 +2341,7 @@ cable_sense_mode

.. py:attribute:: cable_sense_mode

Specifies whether and how the oscilloscope is configured to generate a CableSense signal on the specified channels when the :py:meth:`niscope.Session.CableSenseSignalStart` method is called.
Specifies whether and how the oscilloscope is configured to generate a CableSense signal on the specified channels when the :py:meth:`niscope.Session.cable_sense_signal_start` method is called.

Device-Specific Behavior:
PXIe-5160/5162
Expand All @@ -2366,8 +2364,6 @@ cable_sense_mode

.. note:: the input impedance of the channel(s) to convey the CableSense signal must be set to 50 ohms.

.. note:: One or more of the referenced methods are not in the Python API for this driver.

The following table lists the characteristics of this property.

+----------------+----------------------+
Expand Down Expand Up @@ -3844,11 +3840,7 @@ min_sample_rate

Specify the sampling rate for the acquisition in Samples per second.
Valid Values:
The combination of sampling rate and min record length must allow the digitizer to sample at a valid sampling rate for the acquisition type specified in :py:meth:`niscope.Session.ConfigureAcquisition` and not require more memory than the onboard memory module allows.



.. note:: One or more of the referenced methods are not in the Python API for this driver.
The combination of sampling rate and min record length must allow the digitizer to sample at a valid sampling rate for the acquisition type specified in :py:meth:`niscope.Session.configure_acquisition` and not require more memory than the onboard memory module allows.

The following table lists the characteristics of this property.

Expand Down
26 changes: 5 additions & 21 deletions docs/niswitch/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,10 @@ close
deallocates any memory resources the driver uses. Notes: (1) You must
unlock the session before calling :py:meth:`niswitch.Session._close`. (2) After calling
:py:meth:`niswitch.Session._close`, you cannot use the instrument driver again until you
call :py:meth:`niswitch.Session.init` or :py:meth:`niswitch.Session.InitWithOptions`.
call :py:meth:`niswitch.Session.init` or :py:meth:`niswitch.Session.init_with_options`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not appear to be related to this PR.




.. note:: One or more of the referenced methods are not in the Python API for this driver.

.. note:: This method is not needed when using the session context manager


Expand Down Expand Up @@ -1100,15 +1098,13 @@ send_software_trigger

Sends a software trigger to the switch module specified in the NI-SWITCH
session. When the trigger input is set to :py:data:`~niswitch.TriggerInput.SOFTWARE_TRIG`
through either the :py:meth:`niswitch.Session.ConfigureScanTrigger` or the
through either the :py:meth:`niswitch.Session.configure_scan_trigger` or the
:py:attr:`niswitch.Session.trigger_input` property, the scan does not proceed from
a semi-colon (wait for trigger) until :py:meth:`niswitch.Session.send_software_trigger` is
called.



.. note:: One or more of the referenced methods are not in the Python API for this driver.



set_path
Expand Down Expand Up @@ -1461,13 +1457,9 @@ driver_setup
.. py:attribute:: driver_setup

This property indicates the Driver Setup string that the user specified when initializing the driver.
Some cases exist where the end-user must specify instrument driver options at initialization time. An example of this is specifying a particular instrument model from among a family of instruments that the driver supports. This is useful when using simulation. The end-user can specify driver-specific options through the DriverSetup keyword in the optionsString parameter to the :py:meth:`niswitch.Session.InitWithOptions` method, or through the IVI Configuration Utility.
Some cases exist where the end-user must specify instrument driver options at initialization time. An example of this is specifying a particular instrument model from among a family of instruments that the driver supports. This is useful when using simulation. The end-user can specify driver-specific options through the DriverSetup keyword in the optionsString parameter to the :py:meth:`niswitch.Session.init_with_options` method, or through the IVI Configuration Utility.
If the user does not specify a Driver Setup string, this property returns an empty string.



.. note:: One or more of the referenced methods are not in the Python API for this driver.

The following table lists the characteristics of this property.

+----------------+-----------+
Expand Down Expand Up @@ -1794,11 +1786,7 @@ logical_name
.. py:attribute:: logical_name

A string containing the logical name you specified when opening the current IVI session.
You may pass a logical name to the :py:meth:`niswitch.Session.init` or :py:meth:`niswitch.Session.InitWithOptions` methods. The IVI Configuration utility must contain an entry for the logical name. The logical name entry refers to a virtual instrument section in the IVI Configuration file. The virtual instrument section specifies a physical device and initial user options.



.. note:: One or more of the referenced methods are not in the Python API for this driver.
You may pass a logical name to the :py:meth:`niswitch.Session.init` or :py:meth:`niswitch.Session.init_with_options` methods. The IVI Configuration utility must contain an entry for the logical name. The logical name entry refers to a virtual instrument section in the IVI Configuration file. The virtual instrument section specifies a physical device and initial user options.

The following table lists the characteristics of this property.

Expand Down Expand Up @@ -2563,11 +2551,7 @@ simulate
.. py:attribute:: simulate

Specifies whether or not to simulate instrument driver I/O operations. If simulation is enabled, instrument driver methods perform range checking and call Ivi_GetAttribute and Ivi_SetAttribute methods, but they do not perform instrument I/O. For output parameters that represent instrument data, the instrument driver methods return calculated values.
The default value is False. Use the :py:meth:`niswitch.Session.InitWithOptions` method to override this value.



.. note:: One or more of the referenced methods are not in the Python API for this driver.
The default value is False. Use the :py:meth:`niswitch.Session.init_with_options` method to override this value.

The following table lists the characteristics of this property.

Expand Down
9 changes: 9 additions & 0 deletions generated/nidigital/_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def __init__(self, ctypes_library):
self.niDigital_EnableSites_cfunc = None
self.niDigital_EndChannelMap_cfunc = None
self.niDigital_ExportSignal_cfunc = None
self.niDigital_FetchCaptureWaveformU32_cfunc = None
self.niDigital_FetchHistoryRAMCycleInformation_cfunc = None
self.niDigital_FetchHistoryRAMCyclePinData_cfunc = None
self.niDigital_FetchHistoryRAMScanCycleNumber_cfunc = None
Expand Down Expand Up @@ -528,6 +529,14 @@ def niDigital_ExportSignal(self, vi, signal, signal_identifier, output_terminal)
self.niDigital_ExportSignal_cfunc.restype = ViStatus # noqa: F405
return self.niDigital_ExportSignal_cfunc(vi, signal, signal_identifier, output_terminal)

def niDigital_FetchCaptureWaveformU32(self, vi, site_list, waveform_name, samples_to_read, timeout, data_buffer_size, data, actual_num_waveforms, actual_samples_per_waveform): # noqa: N802
with self._func_lock:
if self.niDigital_FetchCaptureWaveformU32_cfunc is None:
self.niDigital_FetchCaptureWaveformU32_cfunc = self._library.niDigital_FetchCaptureWaveformU32
self.niDigital_FetchCaptureWaveformU32_cfunc.argtypes = [ViSession, ctypes.POINTER(ViChar), ctypes.POINTER(ViChar), ViInt32, ViReal64, ViInt32, ctypes.POINTER(ViUInt32), ctypes.POINTER(ViInt32), ctypes.POINTER(ViInt32)] # noqa: F405
self.niDigital_FetchCaptureWaveformU32_cfunc.restype = ViStatus # noqa: F405
return self.niDigital_FetchCaptureWaveformU32_cfunc(vi, site_list, waveform_name, samples_to_read, timeout, data_buffer_size, data, actual_num_waveforms, actual_samples_per_waveform)

def niDigital_FetchHistoryRAMCycleInformation(self, vi, site, sample_index, pattern_index, time_set_index, vector_number, cycle_number, num_dut_cycles): # noqa: N802
with self._func_lock:
if self.niDigital_FetchHistoryRAMCycleInformation_cfunc is None:
Expand Down
Loading