* Upgrade to allow reading complex-valued data directly.

Please see the documentation of text_input.read_items for more detail.
master
wirawan 14 years ago
parent 71474e2973
commit 96d1f9afd7
  1. 61
      iofmt/text_input.py

@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
# $Id: text_input.py,v 1.1 2010-09-27 19:54:05 wirawan Exp $ # $Id: text_input.py,v 1.2 2010-09-30 17:23:34 wirawan Exp $
# #
# wpylib.iofmt.text_input module # wpylib.iofmt.text_input module
# Quick-n-dirty text input utilities # Quick-n-dirty text input utilities
@ -146,6 +146,13 @@ class text_input(object):
If the tuple contains the third field, it is used as the name of the field; If the tuple contains the third field, it is used as the name of the field;
otherwise the fields are named f0, f1, f2, .... otherwise the fields are named f0, f1, f2, ....
Complex data (floating-point only) must be specified as a tuple of two columns
containing the real and imaginary data, like this:
((2, 3), complex, 'ampl')
or
((7, 9), complex) # fine to interleave column with something else
Additional keyword options: Additional keyword options:
* deftype: default datatype * deftype: default datatype
* maxcount: maximum number of records to be read * maxcount: maximum number of records to be read
@ -154,26 +161,50 @@ class text_input(object):
""" """
deftype = kwd.get("deftype", float) deftype = kwd.get("deftype", float)
# float_fields extracts the desired columns and converts them to floats class register_item_t:
flds = [] flds = []
cols = [] cols = []
complex_types = (complex, numpy.complexfloating)
def add(self, col, fldname, type):
dtype = numpy.dtype(type)
t = dtype.type
dsamp = t() # create a sample
# Special handling for complex:
# -- unfortunately this detection fails because even real
# numbers have its 'imag' attribute:
#dattrs = dir(dsamp)
#if "imag" in dattrs and "real" in dattrs:
if isinstance(dsamp, numpy.complexfloating):
dtype_elem = dsamp.real.dtype
t_elem = dtype_elem.type
conv_func = lambda v, c: t(t_elem(v[c[0]]) + 1j*t_elem(v[c[1]]))
self.cols.append((conv_func, col))
self.flds.append((fldname, dtype))
else:
# other datatypes: much easier
# Simply get the string, and use numpy to convert to the datatype
# on-the-fly
conv_func = lambda v, c: t(v[c])
self.cols.append((conv_func, col))
self.flds.append((fldname, dtype))
reg = register_item_t()
for (i,c) in zip(xrange(len(col_desc)), col_desc): for (i,c) in zip(xrange(len(col_desc)), col_desc):
if type(c) == int: if type(c) == int:
cols.append(c) reg.add(c, 'f' + str(i), deftype)
flds.append(('f' + str(i), deftype))
elif len(c) == 1: elif len(c) == 1:
cols.append(c[0]) reg.add(c[0], 'f' + str(i), deftype)
flds.append(('f' + str(i), deftype))
elif len(c) == 2: elif len(c) == 2:
cols.append(c[0]) reg.add(c[0], 'f' + str(i), c[1])
flds.append(('f' + str(i), c[1]))
elif len(c) == 3: elif len(c) == 3:
cols.append(c[0]) reg.add(c[0], c[2], c[1])
flds.append((c[2], c[1])) else:
raise ValueError, \
"Invalid column specification: %s" % (c,)
#print cols cols = reg.cols
#print flds flds = reg.flds
get_fields = lambda vals : tuple([ vals[col] for col in cols ]) get_fields = lambda vals : tuple([ filt(vals,col) for (filt,col) in cols ])
if "maxcount" in kwd: if "maxcount" in kwd:
#print "hello" #print "hello"
rslt = [ get_fields(vals.split()) for (c,vals) in zip(xrange(kwd['maxcount']),self) ] rslt = [ get_fields(vals.split()) for (c,vals) in zip(xrange(kwd['maxcount']),self) ]

Loading…
Cancel
Save