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
To read the data in and then
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
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!
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
(). 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.