Skip to content

Commit a990af5

Browse files
committed
Ensure waveform record and data types match properly
1 parent 71361af commit a990af5

File tree

1 file changed

+28
-36
lines changed

1 file changed

+28
-36
lines changed

softioc/builder.py

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -109,44 +109,28 @@ def Action(name, **fields):
109109
return boolOut(name, always_update = True, **fields)
110110

111111

112-
# Converts numpy character code to FTVL value.
113-
NumpyCharCodeToFtvl = {
114-
# The following type codes are supported directly:
115-
'B': 'UCHAR', # ubyte
116-
'b': 'CHAR', # byte
117-
'H': 'USHORT', # ushort
118-
'h': 'SHORT', # short
119-
'i': 'LONG', # intc
120-
'L': 'ULONG', # uint
121-
'l': 'LONG', # int_
122-
'f': 'FLOAT', # single
123-
'd': 'DOUBLE', # float_
124-
# noqa 'S': 'STRING', # str_
125-
126-
# The following type codes are weakly supported by pretending that
127-
# they're related types.
128-
'?': 'CHAR', # bool_
129-
'p': 'LONG', # intp
130-
'I': 'ULONG', # uintc
131-
'P': 'ULONG', # uintp
132-
133-
# The following type codes are not supported at all:
134-
# q longlong Q ulonglong g longfloat
135-
# F csingle D complex_ G clongfloat
136-
# O object_ U unicode_ V void
112+
# Converts numpy dtype name to FTVL value.
113+
NumpyDtypeToDbf = {
114+
'int8': 'CHAR',
115+
'uint8': 'UCHAR',
116+
'int16': 'SHORT',
117+
'uint16': 'USHORT',
118+
'int32': 'LONG',
119+
'uint32': 'ULONG',
120+
'float32': 'FLOAT',
121+
'float64': 'DOUBLE',
137122
}
138123

139124
# Coverts FTVL string to numpy type
140125
DbfStringToNumpy = {
141-
# noqa 'STRING': numpy.dtype('S40'), # Don't think we want this!
142-
'CHAR': numpy.dtype('int8'),
143-
'UCHAR': numpy.dtype('uint8'),
144-
'SHORT': numpy.dtype('int16'),
145-
'USHORT': numpy.dtype('uint16'),
146-
'LONG': numpy.dtype('int32'),
147-
'ULONG': numpy.dtype('uint32'),
148-
'FLOAT': numpy.dtype('float32'),
149-
'DOUBLE': numpy.dtype('float64'),
126+
'CHAR': 'int8',
127+
'UCHAR': 'uint8',
128+
'SHORT': 'int16',
129+
'USHORT': 'uint16',
130+
'LONG': 'int32',
131+
'ULONG': 'uint32',
132+
'FLOAT': 'float32',
133+
'DOUBLE': 'float64',
150134
}
151135

152136

@@ -167,7 +151,7 @@ def _waveform(value, fields):
167151
'Can\'t specify FTVL and datatype together'
168152
datatype = numpy.dtype(fields.pop('datatype'))
169153
elif 'FTVL' in fields:
170-
datatype = DbfStringToNumpy[fields['FTVL']]
154+
datatype = numpy.dtype(DbfStringToNumpy[fields['FTVL']])
171155
else:
172156
# No datatype specified, will have to infer from initial value
173157
datatype = None
@@ -177,6 +161,14 @@ def _waveform(value, fields):
177161
value, = value
178162
initial_value = device._require_waveform(value, datatype)
179163
length = fields.pop('length', len(initial_value))
164+
165+
# Special case for [u]int64: if the initial value comes in as 64 bit
166+
# integers cannot represent that, so recast it as [u]int32
167+
if datatype is None:
168+
if initial_value.dtype == numpy.int64:
169+
initial_value = numpy.require(initial_value, numpy.int32)
170+
elif initial_value.dtype == numpy.uint64:
171+
initial_value = numpy.require(initial_value, numpy.uint32)
180172
else:
181173
initial_value = numpy.array([], dtype = datatype)
182174
length = fields.pop('length')
@@ -187,7 +179,7 @@ def _waveform(value, fields):
187179
fields['_wf_dtype'] = datatype
188180

189181
fields['NELM'] = length
190-
fields['FTVL'] = NumpyCharCodeToFtvl[datatype.char]
182+
fields['FTVL'] = NumpyDtypeToDbf[datatype.name]
191183

192184

193185
def Waveform(name, *value, **fields):

0 commit comments

Comments
 (0)