Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated run_writedataset.m to include streamed event markers + pnet.c 64-bit bugfix #1

Open
wants to merge 5 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 53 additions & 7 deletions code/online_plugins/Generic/run_writedataset.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,34 @@ function run_writedataset(varargin)
stream.xmax = stream.xmin + (stream.pnts-1)/stream.srate;
[fp fn fe] = fileparts(out_filename);
% remove superfluous fields
eeg = rmfield(stream,{'buffer','smax','buffer_len','timestamps','timestamps_len','timestamps_ptr','streamid'});
eeg = rmfield(stream,{'buffer','smax','buffer_len','timestamps','timestamps_len','tmax','streamid'});
stream.timestamp_at_beginning = toc(uint64(0));
eeg = pop_saveset(eeg,'filename',[fn fe],'filepath',fastif(isempty(fp),env_translatepath('bcilab:/userdata'),fp),'savemode','twofiles');
% re-create the fdt file...
delete(fullfile(eeg.filepath, eeg.datfile));
fid = fopen(fullfile(eeg.filepath, eeg.datfile),'wb','ieee-le');
if fid == -1
error('Cannot write output file, check permission and space.'); end;

% create a temporary text file to store stream event markers
event_filename = env_translatepath(['bcilab:/userdata/', fn, '_events.txt']);
marker_fid = fopen(event_filename, 'w+');
if marker_fid == -1
error('Cannot write marker output file, check permission and space.');
end
% write a basic header to the event marker file
fprintf(marker_fid, '%s\t%s\n', 'type', 'latency');

% create timer (which periodically writes to the stream)
t = timer('ExecutionMode','fixedRate', 'Name',[in_stream '_write_timer'], 'Period',1/update_freq, ...
'StartDelay',start_delay, 'TimerFcn',@(obj,varargin) append_data(in_stream,fid,stream.streamid,obj,eeg));
'StartDelay',start_delay, 'TimerFcn',@(obj,varargin) append_data(in_stream,fid,marker_fid,stream.streamid,obj,eeg));

% start timer
start(t);


% timer callback: visualization
function append_data(stream,fid,streamid,timerhandle,eeg)
function append_data(stream,fid,marker_fid,streamid,timerhandle,eeg)
try
% check if the stream and the predictor are still there
s = evalin('base',stream);
Expand All @@ -68,25 +78,61 @@ function append_data(stream,fid,streamid,timerhandle,eeg)
% get an updated chunk of data
samples_to_get = min(s.buffer_len, s.smax-ftell(fid)/(4*s.nbchan));
chunk = s.buffer(:, 1+mod(s.smax-samples_to_get:s.smax-1,s.buffer_len));

% and write it into the file
fwrite(fid,chunk,'float');
fwrite(fid,chunk,'float');

% check if this data chunk contains any event markers
marker_chunk = s.marker_pos(:, 1+mod(s.smax-samples_to_get:s.smax-1,s.buffer_len));

% if so, write them into the marker file
if nnz(marker_chunk) > 0
% find the sample(s) in this chunk with events
[marker_pos_in_sample, marker_pos_in_chunk] = find(marker_chunk);

% EEG samples which correspond to positions in the chunk
chunk_samples = s.smax - (samples_to_get - 1) : s.smax;

for m = 1:length(marker_pos_in_chunk)
marker_idx = marker_chunk(marker_pos_in_sample(m), marker_pos_in_chunk(m));
marker_type = s.marker_buffer(marker_idx).type;
marker_sample_whole = chunk_samples(marker_pos_in_chunk(m));
marker_sample_fractional = s.marker_buffer(marker_idx).latency;
marker_sample = marker_sample_whole + marker_sample_fractional;
fprintf(marker_fid, '%s\t%i\n', marker_type, marker_sample);
end
end

catch e
if ~strcmp(e.identifier,'MATLAB:UndefinedFunction')
env_handleerror(e); end
finalize_dataset(fid,eeg);
finalize_dataset(fid,marker_fid,eeg);
% interrupted: make sure that the file gets closed
stop(timerhandle);
delete(timerhandle);
end


function finalize_dataset(fid,EEG)
function finalize_dataset(fid,marker_fid,EEG)
samples = ftell(fid)/(4*EEG.nbchan);
fclose(fid);
EEG.pnts = samples;
EEG.data = EEG.datfile;
EEG.xmax = EEG.xmin + (EEG.pnts-1)/EEG.srate;
EEG.timestamp_at_end = toc(uint64(0));

% load the event marker file from disk and include the markers in the EEG .set
marker_file = [EEG.filepath, filesep, regexprep(EEG.filename, '.set', '_events.txt')];
frewind(marker_fid);
marker_data = textscan(marker_fid, '%s%d', 'Delimiter', '\t', 'HeaderLines', 1);
if ~isempty(marker_data{1})
EEG.event = struct('type', marker_data{1}', 'latency', num2cell(marker_data{2}'), ...
'urevent', num2cell((1:length(marker_data{1}))));
end
fclose(marker_fid);
delete(marker_file);

save(fullfile(EEG.filepath, EEG.filename), '-v6', '-mat', 'EEG');



18 changes: 18 additions & 0 deletions code/online_plugins/Neuroscan/BCILAB.readme
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
README for Neuroscan Scan Plugin for BCILAB
Author: Visual Attention Lab, Dan Roberts, and Nick Pe�aranda, George Mason University, Spring 2014
Released under the GPLv3, see COPYING.txt
Based on the BrainVision BCILAB plug-in by Hal Greenwald


Plugin to stream EEG data and event markers from Neuroscan Scan software to BCILAB. Has been tested with Scan 4.3 and a NuAmps 40-channel amplifier

Associated Files:

BCILAB/code/online_plugins/Neuroscan:
ns_close.m
ns_open.m
ns_parseheader.m
ns_parseinfo.m
ns_read.m
ns_sendpacket.m
run_readneuroscan.m
Loading