[Eeglablist] importing edf, bdf - memory and speed issues

Andreas Widmann widmann at uni-leipzig.de
Mon Feb 6 10:06:06 PST 2006


Dear all,

Murphy's law:
I'm very sorry, of course the proof of concept I sent to the list on 
Friday contained a malicious little typo in line 52 (introduced while 
cleaning up the code) not changing the result numerically but slowing 
down conversion by factor 2-3. Also the conversion itself could have 
been slightly optimized, however, this does no longer speed up reading, 
since MATLAB's fread function is now the bottleneck. The 680 MB bdf file 
is read now in about 40 s.

Best,
Andreas
-------------- next part --------------
function [EEG,hdr] = simplebdfreader(file)

IN = fopen(file);

try EEG = eeg_emptyset;
catch, end

% Header
hdr.fileformat = fread(IN, 8, '*char')';
hdr.subjectid = fread(IN, 80, '*char')';
hdr.recordid = fread(IN, 80, '*char')';
hdr.startdate = fread(IN, 8, '*char')';
hdr.starttime = fread(IN, 8, '*char')';
hdr.hdrnbytes = str2num(fread(IN, 8, '*char')');
hdr.dataformat = fread(IN, 44, '*char')';
hdr.nblocks = str2num(fread(IN, 8, '*char')');
hdr.blockdur = str2num(fread(IN, 8, '*char')');
hdr.nchannels = str2num(fread(IN, 4, '*char')');

% Channel headers
hdr.labels = cellstr(fread(IN, [16 hdr.nchannels], '*char')');
[EEG.chanlocs(1:hdr.nchannels).labels] = deal(hdr.labels{:});
hdr.type = cellstr(fread(IN, [80 hdr.nchannels], '*char')');
hdr.unit = cellstr(fread(IN, [8 hdr.nchannels], '*char')');
hdr.physmin = str2num(fread(IN, [8 hdr.nchannels], '*char')');
hdr.physmax = str2num(fread(IN, [8 hdr.nchannels], '*char')');
hdr.digmin = str2num(fread(IN, [8 hdr.nchannels], '*char')');
hdr.digmax = str2num(fread(IN, [8 hdr.nchannels], '*char')');
hdr.gain = (hdr.physmax - hdr.physmin) ./ (hdr.digmax - hdr.digmin);
hdr.filter = cellstr(fread(IN, [80 hdr.nchannels], '*char')');
hdr.nsamples = str2num(fread(IN, [8 hdr.nchannels], '*char')');
hdr.reserved = cellstr(fread(IN, [32 hdr.nchannels], '*char')');

if length(unique(hdr.nsamples)) == 1
    hdr.nsamples = unique(hdr.nsamples);
else
    error('Different number of samples per channel.')
end
EEG.srate = hdr.nsamples / hdr.blockdur;
EEG.xmin = 0;
EEG.xmax = hdr.nblocks * hdr.blockdur * 1000;
EEG.trials = 1;
EEG.ref = 'common';

% Allocate memory (essential!)
EEG.data = zeros(hdr.nchannels, hdr.nsamples * hdr.nblocks, 'single');

% h = waitbar(0, 'Reading bdf file: 0% done');
tic

for block = 0:hdr.nblocks - 1
    buf = fread(IN, [3, hdr.nsamples * hdr.nchannels], '*uint8');
    EEG.data(1:hdr.nchannels, hdr.nsamples * block + 1:hdr.nsamples * block + hdr.nsamples) = ...
        reshape(single(buf(1, :)) + 256 * single(buf(2, :)) + 65536 * single(buf(3, :)) - 131072 * single(bitand(buf(3, :), 128)), ...
        hdr.nsamples, hdr.nchannels)';
%     if (block + 1) == ceil(floor((block + 1) / (hdr.nblocks / 100)) * (hdr.nblocks / 100))
%         p = (block + 1) / hdr.nblocks;
%         t = toc;
%         waitbar(p, h, ['Reading bdf file: ' num2str(round(p * 100)) '% done, ' num2str(round((1 - p) / p * t)) ' s left']);
%     end
end

toc
% close(h);

for chan = 1:hdr.nchannels
    EEG.data(chan, :) = hdr.gain(chan) * EEG.data(chan, :);
end

toc

fclose(IN);


More information about the eeglablist mailing list