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

Indexing PhysicalChannelCollection fails for slices and strings containing a list/range of channels #392

Closed
bkeryan opened this issue Jun 2, 2023 · 1 comment · Fixed by #536

Comments

@bkeryan
Copy link
Collaborator

bkeryan commented Jun 2, 2023

Most of the collections in nidaqmx.system support slices (e.g. system.devices[:] or system.devices[1:3]) and lists/ranges of names (e.g. `system.devices["Dev1,Dev2"]). Example:

PS D:\dev\nidaqmx-python> poetry run python
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import nidaqmx.system
>>> system = nidaqmx.system.System.local()
>>> system.devices[:]
[Device(name=aoTester), Device(name=bridgeTester), Device(name=cdaqChassisTester), Device(name=Dev1), Device(name=nidaqmxMultithreadingTester1), Device(name=nidaqmxMultithreadingTester2), Device(name=nidaqmxMultithreadingTester3), Device(name=nidaqmxMultithreadingTester4), Device(name=tsChassisTester), Device(name=tsPowerTester1), Device(name=tsPowerTester2), Device(name=tsVoltageTester1)]
>>> system.devices[1:3]
[Device(name=bridgeTester), Device(name=cdaqChassisTester)]
>>> system.devices["Dev1,aoTester"]
[Device(name=Dev1), Device(name=aoTester)]

PhysicalChannelCollection.__getitem__ has code to handle slices, but it incorrectly sets PhysicalChannel._name to a list of names, which is the wrong data type:

>>> device = system.devices[0]
>>> device.ao_physical_chans
<nidaqmx.system._collections.physical_channel_collection.AOPhysicalChannelCollection object at 0x000002249206F100>
>>> list(device.ao_physical_chans)
[PhysicalChannel(name=aoTester/ao0), PhysicalChannel(name=aoTester/ao1), PhysicalChannel(name=aoTester/ao2), PhysicalChannel(name=aoTester/ao3), PhysicalChannel(name=aoTester/ao4), PhysicalChannel(name=aoTester/ao5), PhysicalChannel(name=aoTester/ao6), PhysicalChannel(name=aoTester/ao7)]
>>> device.ao_physical_chans[:]
PhysicalChannel(name=['aoTester/ao0', 'aoTester/ao1', 'aoTester/ao2', 'aoTester/ao3', 'aoTester/ao4', 'aoTester/ao5', 'aoTester/ao6', 'aoTester/ao7'])
>>> device.ao_physical_chans[1:3]
PhysicalChannel(name=['aoTester/ao1', 'aoTester/ao2'])
>>> device.ao_physical_chans[1:3].ao_output_types
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\dev\nidaqmx-python\generated\nidaqmx\system\physical_channel.py", line 340, in ao_output_types
    val = self._interpreter.get_physical_chan_attribute_int32_array(self._name, 0x2fd9)
  File "D:\dev\nidaqmx-python\generated\nidaqmx\_library_interpreter.py", line 3007, in get_physical_chan_attribute_int32_array
    size_or_code = cfunc(
ctypes.ArgumentError: argument 1: <class 'TypeError'>: bytes or integer address expected instead of list instance

PhysicalChannelCollection.__getitem__'s docstring says it accepts a string containing a list/range of channel names. I think ranges may work for API functions that accept multiple physical channels, but lists do not work because only the first channel has a device name.

>>> device.ao_physical_chans["ao0:1"]
PhysicalChannel(name=aoTester/ao0:1)
>>> device.ao_physical_chans["ao0:1"].ao_output_types
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\dev\nidaqmx-python\generated\nidaqmx\system\physical_channel.py", line 340, in ao_output_types
    val = self._interpreter.get_physical_chan_attribute_int32_array(self._name, 0x2fd9)
  File "D:\dev\nidaqmx-python\generated\nidaqmx\_library_interpreter.py", line 3018, in get_physical_chan_attribute_int32_array
    self.check_for_error(size_or_code)
  File "D:\dev\nidaqmx-python\generated\nidaqmx\_library_interpreter.py", line 6066, in check_for_error
    raise DaqError(extended_error_info, error_code)
nidaqmx.errors.DaqError: You have specified more than one physical channel as the active channel which is not supported. Specify a single physical channel.
Physical Channel Name: aoTester/ao0:1

Status Code: -200752
>>> device.ao_physical_chans["ao0,ao1"]
PhysicalChannel(name=aoTester/ao0,ao1)
>>> device.ao_physical_chans["ao0,ao1"].ao_output_types
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\dev\nidaqmx-python\generated\nidaqmx\system\physical_channel.py", line 340, in ao_output_types
    val = self._interpreter.get_physical_chan_attribute_int32_array(self._name, 0x2fd9)
  File "D:\dev\nidaqmx-python\generated\nidaqmx\_library_interpreter.py", line 3018, in get_physical_chan_attribute_int32_array
    self.check_for_error(size_or_code)
  File "D:\dev\nidaqmx-python\generated\nidaqmx\_library_interpreter.py", line 6066, in check_for_error
    raise DaqError(extended_error_info, error_code)
nidaqmx.errors.DaqError: Device identifier is invalid.
Device Specified: empty string
Suggested Device(s): tsChassisTester, cdaqChassisTester, tsPowerTester1, tsPowerTester2, tsVoltageTester1, nidaqmxMultithreadingTester3, nidaqmxMultithreadingTester2, nidaqmxMultithreadingTester4, nidaqmxMultithreadingTester1, Dev1, bridgeTester, aoTester

Status Code: -200220
@zhindes
Copy link
Collaborator

zhindes commented Mar 6, 2024

Note when fixing this, some tests have worked around this by using the channel_names property of the PhysicalChannelCollection. We should update those to use the collection as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants