views:

1318

answers:

3

I'm trying to convert the following code to Python from MATLAB for an EEG Project (partly because Python's slightly cheaper!)

Hopefully someone can point me in the right direction: I've started to alter it but got bogged down: Particularly trying to find equivalent functions.

Tried scipy.org (NumPy_for_Matlab_Users etc.) but I'm not sure if my arguments are of the right format/number)

I was originally using pyserial

ser.read()

To read the data in and then

ord()

To convert it into an integer, but this MATLAB code goes about it another way ('uchar')

My main issues were with

fopen
fread
find
repmat

And the whole plotting section as I have even less of an idea about that in Python (MatPlotLib?)

MATLAB also tends to start with '1' whereas Python uses 0: I've tried to alter these also but have missed a few I wasn't sure of.

Is Python happy with the whole range separated by colons

...repmat(0:2:10, .....

or not?

So, here is the MATLAB:

% EEG data grabber and plotter

N = 256;    % Required number of sample frames

% Read in a block of data from the OpenEEG board
hCom = serial('COM1','BaudRate',57600,'timeout',5);
fopen(hCom);
numBlocks = (ceil(17*N/256) + 1);
rawdata = zeros(numBlocks*256,1);
for n = 1:numBlocks
    rawdata((0:255) + n*256) = fread(hCom, 256, 'uchar');  % Read data
end
fclose(hCom);

% Convert raw data into a Matlab matrix
% First find the first frame start
startIndex = find(rawdata == 165);
while(rawdata(startIndex(1) + 1) ~= 90)
   startIndex = startIndex(2:end);
end
% Now extract the samples
frameStarts = (0:(N-1))'*17 + startIndex(1);
indices = 4 + repmat(frameStarts, 1, 6) + repmat(0:2:10, length(frameStarts), 1);
eegData = (rawdata(indices)*256 + rawdata(indices + 1)) - 512;
% eegData is now a N by 6 matrix, each column is a channel of sampled data

% Plot time-series data
figure(1)
subplot(2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]');
ylabel('EEG data'); 
% Calculate FFT and plot spectra
subplot(2,1,2)
window = 0.5 - 0.5 * cos(2*pi*(0:255)/255); % Von-Hann Window
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)));
plot((0:127),f(1:128,:))
xlabel('Frequency [Hz]');
ylabel('EEG FFT');

And here's my poor cousin version

import scipy
import serial                       #Serial Module to read serial port
from numpy import ceil,zeros        #Ceil module & zeros for blank matrix

N = 256    #no of sample frames (256 = 1s)

#Reads a block of data from the serial port

ser = serial.Serial('COM18',57600,timeout=5)

scipy.fopen(ser)       #MATLAB CODE: fopen(ser)  is this correct????

numBlocks = (ceil(17*N/256) + 1)
rawdata = scipy.zeros(numBlocks*256,1)
for n = 1:numBlocks
    rawdata((0:255) + n*256) = numpyio.fread(ser,256,'i')  # read each byte as     unsigned integer
end
ser.close()


#convert raw data to MATLAB matrix
#find start of frame (1st Byte always 165, 2nd always 90)

startIndex = find(rawdata == 165);
while (rawdata(startIndex(0) + 1) ~=90) #confirms 165,90 sequence
    startIndex = startIndex(1:end) #uses rest of frame as data
end

#Extraction of sample values

#MATLAB CODE
frameStarts = (0: (N-1))'*17 + startIndex(1);      #'#how to transpose matrix('): zip()??
indices = 4 + (numpy.tile(frameStarts, 1,6)) + (numpy.tile(0:2:10,length(frameStarts), 1); 
eegData = (rawdata(indices)*256 + rawdata(indices +1)) - 512  #values are unsigned     integers 0-1023 and must subtract 512 for actual value
#eeg data now N*6 Matrix each column is a channel of data

#MATLAB CODE: plot time series data  (MatPlotLib?)

figure(1)
subplot (2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]')
ylabel('EEG Voltage')
#fft
subplot(2,1,2)
window = 0.5 - 0.5*cos(2*pi*(0:255)/255);
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)))    '#repmat=tile()? matrix     transposition (')?
plot((0:127),f(1:128,:))
xlabel('Freq [Hz]')
ylabel('EEG FFT')

All suggestions gratefully received!

Dave!

+5  A: 

Um... lots of things.

Python has no end keyword, so you clearly need to read more about Python's syntax.

Python arrays and slices are indexed with [] not (). Ranges are expressed as range(0,10) for example, but slices in the Matlab sense only exist in extension packages like numpy and each one has its own interface.

Yes, you want to use matplotlib for plotting, it has pretty much the same capabilities as Matlab's plotting interface, at least at this level.

It looks like you're guessing that Python will have the same method names as Matlab in some random package. This is not a good plan. Instead, look up the Matlab method in its documentation, which is online, find out exactly what it does, and then read into the Python package documentation for a method that does what you want. This may not exist, but I'm betting that in a program this simple, most of the ones you need will.

The most important thing you need to understand in converting any Matlab code to other languages is the way Matlab arrays work, which is extremely unusual (but excellent for its target applications). Numpy has about the same capabilities, but a completely different notation for them.

The serial module has already given you an open file object on the port, so you don't need the fopen.

I think you need to spend a LOT of time with the documentation for both Python and Matlab, because it's quite clear you understand neither at the moment.

Don't let me discourage you, I'm just being honest about where you're at.

Andrew McGregor
I totally agree with @Andrew McGregor. Porting a program from one to the other is a nice way to learn a language (I'm doing something similar right now from MATLAB to Python) but it's a tough way to learn two languages!
mtrw
+1  A: 

This may or may not work, but you might want to try a Matlab to Python converter such as mat2py. I've never tried them, but it might save some time. Also, there's this page about Matlab to Numpy conversion that might help you get acquainted with the differences between the two.

Justin Peel
+1  A: 

One small point - indexing between the two is different. If you just copy everything from MATLAB to Python, as you seem to have done, you'll be very very confused. MATLAB x(1:5:end) translates to Python x[0::5]. Go back to NumPy for MATLAB Users and scan down to the section called "Linear Algebra Equivalents" (about halfway down the page). It gives a dictionary of how to go back and forth.

mtrw