[SciPy-user] NumPy Newcomer Questions: Reading Data Stream & Building Array
Rich Shepard
rshepard at appl-ecosys.com
Fri Sep 8 13:18:39 EDT 2006
After decades of Fortran and C, I'm quite new to Python and all the great
tools it provides. So, I'd like mentoring in how to most elegantly and
effectively parse data read over a serial port from a scanner, and how to
build a 2D array from it. After this, I'll probably need help in other NumPy
array (matrix) manipulations. But, first things first:
Data are entered on an optical mark readable (OMR) form, which is scanned
and the data sent over a serial line. Each form read transmits 69 bytes;
there are 2 bytes for each "column" (where there is a timing mark on the
edge of the form) and their position within that column determines their
value. The form has two blank lines (with timing marks) and three lines with
labels; these transmit the equivalent of '0' and are not recorded. The final
byte is a carriage return, '\r,' which is translated into a newline ('\n') by
the method.
For each form read I want to record the form number (programmatically
sequentially assigned, starting with '1') and the data from the form as a
row. The total forms read then fill a two-dimensional array.
The two issues with which I would like help are:
How to slice the list of data from the scanner stream into two-byte chunks
(leaving the end-of-record byte to be dealt with separately),
How to build the array so that each form read creates a new row in the
array. While the 31 columns are fixed, the number of rows is indeterminate
until all submitted forms have been read.
I've attached the 95-line 'OnScan.py' to this message; it's a single
function within the application.
TIA,
Rich
--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc.(TM) | Accelerator
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863
-------------- next part --------------
def OnScan(self, event):
""" OMR form timing marks and their meaning:
Col. # Value
-----------------
1 Category labels
2 Category mark
3 Blank line
4 Position labels
5 Polition mark
6 Row labels
7-34 Pairwise comparison votes
A total of 69 bytes are sent in a stream; the last is '\r' for end of record
"""
# scanner row translations
DATA_MAP_BLANK = {
chr(32)+chr(32): 0
}
DATA_MAP_2 = {
chr(32)+chr(36): 'nat',
chr(96)+chr(32): 'eco',
chr(36)+chr(32): 'soc'
}
DATA_MAP_5 = {
chr(32)+chr(36): 'pro',
chr(96)+chr(32): 'neu',
chr(36)+chr(32): 'con'
}
DATA_MAP_7 = {
chr(32)+chr(16): 1.000,
chr(32)+chr(8): 2.000,
chr(32)+chr(4): 3.000,
chr(32)+chr(2): 4.000,
chr(32)+chr(1): 5.000,
chr(64)+chr(32): 6.000,
chr(16)+chr(32): 7.000,
chr(8)+chr(32): 8.000,
chr(4)+chr(32): 9.000,
chr(34)+chr(8): 0.500,
chr(34)+chr(4): 0.333,
chr(34)+chr(2): 0.025,
chr(34)+chr(1): 0.200,
chr(66)+chr(32): 0.167,
chr(18)+chr(32): 0.143,
chr(10)+chr(32): 0.125,
chr(6)+chr(32): 0.111
}
# Open serial port
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
ser.open()
if ser.isOpen() != True:
serial.SerialException
searchString = '\r' # end of card read
vote_id = 0 # card number incremented at start of read loop
newStart = 0 # only > 0 if the run is aborted by the operator
progressMax = 500
omrDialog = wx.ProgressDialog("Scoping Form Input",
"Processing ...", progressMax, style=wx.PD_CAN_ABORT |
wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
keepGoing = True
while True:
vote_id += 1 # vote record number; heads list row & displayed for entry on form
if newStart > 0: # read was aborted (card mis-read? jammed?) and restarted
vote_id = newStart
omrDialog.Resume()
# read the line sent by the OMR reader; record end is '\r'.
line = ser.readline # get all 69 bytes in one chunk
"""
if value == DATA_MAP_BLANK: # skip line if blank or labels
continue
if value == searchString: # we're done with that form
vrecord[:-1] # slice off the terminal comma
vrecord.append('\n') # add a newline
break
vrecord.extend([line, ", "]) # add the pairwise comparison value, a comma, and a space
Now I need to add that vote record to an array, and start a new row """
while keepGoing and vote_id < progressMax: # increment progress dialog
if keepGoing == False:
newStart = vote_id
break
keepGoing = omrDialog.Update(vote_id)
# close the dialog box and serial port
omrDialog.Destroy()
ser.Close()
More information about the SciPy-User
mailing list