-
Notifications
You must be signed in to change notification settings - Fork 0
/
MI_Online_Prediction.m
133 lines (113 loc) · 4.36 KB
/
MI_Online_Prediction.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
%% Refresh
clc; clear; close all;
%% Parameters
% Insert the recording folder here!
recordingFolder = '' % For example: 'C:\Users\Raz\BCI4ALS\Recordings\ONLINE_TEST';
config_param
% dataFolder is the folder with the `.mat` files that are the output of MI4
% Insert the recording folder here!
dataFolder = '' % For example: 'C:\Users\Raz\GitRepos\BCI4ALS\data\michael';
addpath(string(lslPath)); % lab streaming layer library
addpath(string(lslPath) + '\bin'); % lab streaming layer bin
addpath(string(eeglabPath));
eeglab nogui;
% Setup Python interperter
% TODO: consider adding Python interperter path to config_params
% INSERT PATH TO THE VIRTUAL ENVIRONMENT'S PYTHON EXECUTABLE!
pythonEvnPath = '' % For example: 'C:\Users\Raz\anaconda3\envs\BCI\python.exe'
try
pyenv('Version',pythonEvnPath);
catch e
disp(e);
end
% Paradigm
InitWait = waitList(1); % before trials prep time
readyLength = waitList(2); % time "ready" on screen
cueLength = waitList(3); % time for each cue
nextLength = waitList(4); % time "next" on screen
% MI4 results
load(strcat(dataFolder,'\W.mat')); %load W for csp
load(strcat(dataFolder,'\SelectedIdx.mat')); %load indexes of selected features
% online params
online_trails = 1;
feedback_returns = 1;
buffer = [];
ALL_FEATURES = [];
myPrediction = []; % predictions vector
decCount = 0;
successCount = 0;
onlineTrainingVec = prepareTraining(online_trails,MI1params.numClasses); % vector with the conditions for each trial
numChans = size(EEG_chans,1);
MI2params.offline = 0;
MI2params.plot = 0;
MI4params.offline = 0;
%% Start LSL
%% open stream
disp('Loading the Lab Streaming Layer library...');
lib = lsl_loadlib(); % load the LSL library
disp('Opening Marker Stream...');
info = lsl_streaminfo(lib,'MarkerStream','Markers',1,0,'cf_string','myuniquesourceid23443');
outletStream = lsl_outlet(info); % create an outlet stream using the parameters above
disp('Resolving an EEG Stream...');
result = {};
lslTimer = tic;
while isempty(result)
result = lsl_resolve_byprop(lib,'type','EEG');
end
disp('Success resolving!');
EEG_Inlet = lsl_inlet(result{1});
%% Start TCP connection
% Verify that the Python GUI's client and
% this server use the same HOST and PORT
HOST="localhost";
PORT=12345;
CONNECTION_TIMEOUT = 60 * 30; % in seconds - we deliberately allow a long time before closing the connection
disp('Starting TCP server...');
server = tcpserver(HOST, PORT, "Timeout", CONNECTION_TIMEOUT);
fprintf('TCP server started on %s, port %d \n', server.ServerAddress, server.ServerPort);
%% Start Training
RUN_SERVER = true;
% Note: this server can be extended to another function
% that servers all interactions between the GUI and the Matlab "backend"
while RUN_SERVER
request = readline(server);
if request=="START"
cur_data = EEG_Inlet.pull_chunk();
pause(0.1);
trialStart = tic;
buffer = [];
while size(buffer,2) <= trialLength*fs
cur_data = EEG_Inlet.pull_chunk();
pause(0.1);
if ~isempty(cur_data)
buffer = [buffer, cur_data];
else
disp(strcat('no data to pull after ', num2str(toc(trialStart)), 'seconds'));
end
end
%
EEG = pop_importdata('dataformat', 'matlab', 'nbchan', numChans,...
'data', buffer, 'srate', fs, 'pnts', 0, 'xmin', 0);
decCount = decCount + 1;
[EEG_arr] = preprocess(EEG, recordingFolder, eeglabPath, unused_channels, MI2params);
EEG_data = EEG_arr(end).data;
MIData = [];
for channel=1:numChans
MIData(1, channel, :) = EEG_data(channel, :);
end
[MIFeatures] = feature_engineering(recordingFolder, MIData, bands, times, W, MI4params, feature_setting);
FeaturesSelected = MIFeatures(:, SelectedIdx);
prediction = predict(FeaturesSelected);
write(server, int2str(prediction), "string");
% TODO: re-consider whether we need the STOP functionallity
elseif request=="STOP"
RUN_SERVER = false;
disp("Stop request acknowledged");
continue;
else
resp = sprintf("Unknown request type: %s", request);
write(server, resp, "string");
end
end
%% End of experiment
disp('Finished');