Skip to content

Waveform of strings no longer works #101

Closed

Description

@coretl

This:

labels = builder.WaveformOut(
    "ENUM:LABELS", initial_value=[b"ZERO", b"ONE", b"MANY"]
)

used to give a waveform with FTVL of STRING under pythonSoftIOC 3.2, but now it gives:

Traceback (most recent call last):
  File "/dls/science/users/tmc43/common/python/PandABlocks-client/pandablocks/ioc/ioc.py", line 1490, in create_record
    self, record_name, field_info, str_vals
  File "/dls/science/users/tmc43/common/python/PandABlocks-client/pandablocks/ioc/ioc.py", line 943, in _make_bit_mux
    initial_value=[b"ZERO", b"ONE", b"MANY"]
  File "/scratch/tmc43/pipenv/PandABlocks-client-0xhNhEPE/lib/python3.7/site-packages/softioc/builder.py", line 226, in WaveformOut
    _waveform(value, fields)
  File "/scratch/tmc43/pipenv/PandABlocks-client-0xhNhEPE/lib/python3.7/site-packages/softioc/builder.py", line 215, in _waveform
    fields['FTVL'] = NumpyDtypeToDbf[datatype.name]
KeyError: 'bytes32'

Activity

  1. Araneidae commented on Aug 24, 2022

    @Araneidae
    Collaborator

    Interesting regression. Do you feel like bisecting it? Unfortunately 3.2 is quite a long way back, it may be simpler to reimplement the functionality!

    I didn't realise that arrays of strings actually worked.

  2. AlexanderWells-diamond commented on Aug 24, 2022

    @AlexanderWells-diamond
    Collaborator

    I'm investigating it now. There has been a large amount of changes in this area unfortunately. I'll see what I can do.

  3. AlexanderWells-diamond commented on Aug 24, 2022

    @AlexanderWells-diamond
    Collaborator

    I've found most of the missing pieces from the 3.2 -> 4.* change that broke this:

    The mapping between types changed rather a lot. The old NumpyCharCodeToDbr mapping was replaced by NumpyDtypeToDbf (and other bits). Adding this mapping: 'bytes32': 'STRING' means we can initialize a Waveform of the given form without error, but caget'ing it doesn't work right.

    The second major change is WaveformBase._write_value. Previously there was a call to numpy.require() using a saved dtype (inferred earlier in the initialisation process) that was set to "S40" i.e. an EPICS string. That conversion step just doesn't exist anymore. Hacking it by just adding this line at the beginning of the method: value = numpy.require(value, dtype=numpy.dtype('S40')) makes everything almost work:

    >>> caget("AAA:AAA")
    ca_array(['ZERO', '', ''], dtype='<U4')
    

    I haven't yet worked out why elements 1 and 2 are now empty. And I'm not sure what the proper fix of the _write_value method is, but it's nearly there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions