Skip to content

Instantly share code, notes, and snippets.

@diego898
Created October 22, 2016 18:16
Show Gist options
  • Save diego898/fc61bbddfdb8d24849ed3b7975e28ff0 to your computer and use it in GitHub Desktop.
Save diego898/fc61bbddfdb8d24849ed3b7975e28ff0 to your computer and use it in GitHub Desktop.
Some files to batch convert snap-master generated SMA files, using a slightly customized version of EEGLAB's snapread() function.
% batchConvertSMA() - Convert all SMA files in current directory and
% sub-directories to CSV files. Additionally extract the
% header and save as a txt file.
function [data,params,head,events] = batchConvertSMA()
% Grab all SMA files in current directory and sub-directories
files = dir('**/*.SMA');
% count number of SMA files
numOfFiles = length(files);
% loop through each file
for i=1:numOfFiles
% get current file
currentFile = files(i);
fprintf('\n Converting %s ...\n',currentFile.name);
% generate paths to read/write to
pathToRead = strcat(currentFile.folder,'/',currentFile.name);
pathToWriteCSV = strcat(currentFile.folder,'/',strrep(currentFile.name,'SMA','csv'));
pathToWriteTXT = strcat(currentFile.folder,'/',strrep(currentFile.name,'SMA','txt'));
% use custom readsnap function
[data,params,header] = readsnap(pathToRead);
% write csv file
dlmwrite(pathToWriteCSV,data, 'precision',30);
% write header file
dlmwrite(pathToWriteTXT,header,'delimiter','');
end
% readsnap() - Read data in Snap-Master Standard Binary Data File Format
% Reads Snap-Master header and data matrix (nchans,nframes).
% Ref: Users Guide, Snap-Master for Windows (1997) p. 4-19
% Note: This is an *altered* version of the original snapread
% found in EEGLAB.
% Usage:
% >> data = readsnap(filename); % read .SMA file data
% >> [data,params,head,events] = readsnap(filename,seekframes);
% % save parameters, event list
% Inputs:
% filename = string containing whole filename of .SMA file to read
% seekframes = skip this many initial time points {default 0}
% Output:
% data = data matrix, size(nchans,nframes)
% params = [nchannels, nframes, srate]
% head = complete char file header
% events = vector of event frames (lo->hi transitions on event channel);
% See source to set EVENT_CHANNEL and EVENT_THRESH.
%
% Note: This is based off the original snapread() found in EEGLAB. This version
% reverses the ordering of the output arguments, so that we can always return
% the params and header of file without having to split into events.
%
% Author of Revision: Diego Mesa, La Jolla, October 20, 2016
% Original Authors: Scott Makeig & Tzyy-Ping Jung, SCCN/INC/UCSD, La Jolla,
% January 31, 2000
%
% Please see the original version for copyright information
function [data,params,head,events] = readsnap(file,seekframes)
EVENT_CHANNEL = 1; % This channel assumed to store event pulses only!
EVENT_THRESH = 2.3; % Default event threshold (may need to adjust!!!!)
if nargin < 2
seekframes = 0;
end
data = [];
events = [];
params = [];
head = [];
%
%%%%%%%%%%%%%%%%%%%%%%%%%% Open file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
fid = fopen(file,'r', 'ieee-le');
if fid<1
fprintf('\nreadsnap(): Could not open file %s.\n\n',file)
return
else
fprintf('\n Opened file %s for reading...\n',file);
end
%
%%%%%%%%%%%%%%%%%%%%%%%%%% Read header %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Read header and extract info
numbegin=0;
head = [];
while ~numbegin,
line =fgets(fid);
head = [head line];
if (length(line)>=8 & line(1:8)=='"NCHAN%"')
nchans=str2num(line(findstr(line,'=')+1:end-1));
end
if (length(line)>= 12 & line(1:12)=='"NUM.POINTS"')
nframes=str2num(line(findstr(line,'=')+1:end-1));
end
if (length(line)>= 10 & line(1:10)=='"ACT.FREQ"')
srate=str2num(line(findstr(line,'=')+1:end-1));
end
if (length(line)>= 4 & line(1:4)=='"TR"')
head = head(1:length(head)-length(line));
line =fgets(fid); % get the time and date stamp line
numbegin=1;
end
end
params = [nchans, nframes, srate];
fprintf(' Number of channels: %d\n',nchans);
fprintf(' Number of data points: %d\n',nframes);
fprintf(' Sampling rate: %3.1f Hz\n',srate);
fseek(fid,1,0); % skip final hex-AA char
%
%%%%%%%%%%%%%%%%%%% Test for correct file length %%%%%%%%%%%%%%%%%%%%
%
datstart = ftell(fid); % save current position in file
fseek(fid,0,'eof'); % go to file end
datend = ftell(fid); % report position
discrep = (datend-datstart) - nchans*nframes*4;
if discrep ~= 0
fprintf(' ***> Note: File length does not match header information!\n')
fprintf(' Difference: %g frames\n',discrep/(4*nchans));
end
fseek(fid,datstart,'bof'); % seek back to data start
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Read data %%%%%%%%%%%%%%%%%%%%%%%%%%
%
if seekframes > 0
fprintf(' Omitting first %d frames of data.\n',seekframes)
fprintf('moving %d bytes\n',seekframes*nchans*4);
fsq = fseek(fid,seekframes*nchans*4,'cof')
if fsq<0
fsqerr = ferror(fid);
fprintf('fseek() error: %s\n',fsqerr);
return
end
end
[data count] = fread(fid,[nchans,nframes],'float'); % read data frame
if count<nchans*(nframes-seekframes)
fprintf('\nreadsnap(): Could not read %d data frames.\n Only %g read.\n\n',...
nframes,count/nchans);
return
else
fprintf('\n Read %d frames, each one sync channel(%d) and %d data channels.\n',...
nframes,EVENT_CHANNEL,nchans-1);
end
if nargout>3
fprintf(' Finding event transitions (>%g) on channel %d ...\n',...
EVENT_THRESH,EVENT_CHANNEL);
events = zeros(EVENT_CHANNEL,nframes);
for n=2:nframes
if abs(data(EVENT_CHANNEL,n-1)) < EVENT_THRESH ...
& abs(data(EVENT_CHANNEL,n)) > EVENT_THRESH
events(n) = 1;
end
end
fprintf(' Total of %d events found.\n',sum(events));
data = data(2:nchans,:); % eliminate channel 1
fprintf(' Event channel %d removed from output.\n',EVENT_CHANNEL);
params(1) = nchans-1;
end
fprintf('\n');
fclose('all');
@diego898
Copy link
Author

To have a version of batchConvertSMA() that saves mat files instead of csv, make the following changes:

%  pathToWriteCSV = strcat(currentFile.folder,'/',strrep(currentFile.name,'SMA','csv'));
    pathToWriteMAT = strcat(currentFile.folder,'/',strrep(currentFile.name,'SMA','mat'));   
...
% write MAT file
    save(pathToWriteMAT,'data')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment