Giter Site home page Giter Site logo

lkorczowski / gipseeg Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 1.0 15.15 MB

Personal Matlab Toolbox written for EEG processing and classification during my thesis @GIPSA-lab. Not maintained but released for educational purpose.

License: MIT License

MATLAB 88.89% Mercury 0.05% HTML 7.68% M 2.76% Ruby 0.46% Mathematica 0.17%

gipseeg's Introduction

LK_toolbox (a.k.a gipseeg)

Personal Matlab Toolbox written for EEG processing and classification during the begginning of my thesis @GIPSA-lab (2013-2015). Not well maintained but released for educational purpose.

It is mostly unfinished job. Modules of my work has been released into other repositories in more advanced state. After 2015, the code was maintained in a different (private) repo.

If you found this repo and plan to use it (or part of it), please read below before.

few words

Because I came from signal processing, I wasn't fond of the complex eeglab/fieldtrip structures with never ending attributes and parameters. So I tried to build the "minimum-viable" structure to process and classify EEG on my own and it was probably not better than EEG/fieldtrip structure anyway. While I tried to maintain this code at some point, the effort were dropped because only few engineers and PhD students were using it and I decided to share only piece of cleaner code in different repo. I finally, after many years of this code roting on my computer, decided to upload the ugly monster. Let say it is a monument of "how to not start a thesis".

Install

to install LK TOOLBOX and related functions please, launch the script "installer" (run in matlab) thus you'll have acces to all the functions and script. For some functions, external requirements be needed (see external section below)

The toolbox

The content

Of course the library is far from being well organized because of poor decisions during my thesis so don't expect to find everything perfectly in place. Also, because I had to work on several papers at the same time, sometimes functions have several versions co-existing to not loose compatibility of my code.

LIB folder

This folder contains mostly original work.

  • preproc: preprocessing data, epoching, convertion of trigger channel, some basic math fonctions
  • Epoch: averaging, and other methods for organizing and processing EEG epochs
  • processing: preprocess your eeg, withen your data, cospectra, etc.
  • fileio (save-load-convert): All operations of loading. Out toolbox should be fully compatible for loading, converting on the following format : .mat
  • classif: classification methods using Riemannian Geometry
  • hyperscanning: classification and processing of simultaneous recording of multiple brains
  • metrics: more Riemannian Geometry metrics used that were not in other toolbox
  • synthetic: code to simulate EEG
  • CSTP: dev of the repo https://github.com/lkorczowski/acstp (please use that one instead)
  • BSS: dev prior of the release of https://github.com/lkorczowski/CAJD (please use that one instead) and many more...

script

A messy folder containing plenty of experiments. Not very worthy if you don't have the data in hand but usefull if you want to see how the functions in lib folder were used.

external

I give some of the code that is mandatory for running my toolbox. But I'll probably need to add the two following folders if some functions doesn't work:

the gipseeg structure

While I tried that most of the funtion can work directly with matrix (and not complicated structures), it may be easier to use to encapsulate your data into a structure, e.g. for using preprocessingEEG or plotEEG.

Dimensions and nomenclature :

  • variable - name - (scale) - Fieldtrip : dimord (variable name)
  • t - samples (T) FT: time (time)
  • n - channels (N) FT: chan (label)
  • k - trials (K) FT: rpt (trial)
  • m - subjects (M) FT: subj (‘’)
  • f - frequencies (F) FT: freq (freq)
  • z - classes (Z) FT: rpt (trialinfo)
  • c - conditions (C) FT: rpt (trialinfo) constrains T>N, T>M, K>>M
FIELDNAME SIZE/TYPE DESCRIPTION fieldtrip eeglab autre
Fs scalar sample rate in Hz fsample ‘srate’ fs
Trigger [nb samples x1 ] Trigger channel of '0' with '1' at the start of each sweep. There are [nb epochs] '1' sampleinfo
EpochClass [nb epochs x1] class of the sweeps (0 for Non-TARGET, 1 for TARGET). trialinfo
Channels [nb samples x nb channels] continuous eeg recording
NoiseTrigger* [nb samples x1 ] the equivalent of Trigger but for the sweep of the noise.
By default, it takes the same.
ElectrodesName* {1 x nb channels} the names of the electrodes label

ACSTPoptions is a structure with

     Epoch_size: scalar, the length of the epoch window (in samples)
LatencyCorr_max: scalar, the maximum of samples for the latency
                  correction. Set 0 to disable the Latency correction.
Mask_Electrodes: vector of the selectionned electrodes. Usefull for the
                 automatic subspace selection (BestPz) and latency
                 correction (Latency).
      Mask_Time: vector of the selectionned sample. Usefull for the
                 automatic subspace selection (BestPz) and latency
                 correction (Latency).
MaxIterLatency*: scalar, the maximum iteration allowed to compute the
                  latency correction. Default: 10.
   SubspaceDim*: vector, containing all the subspace dimension (nb electrodes)
                 to test in descent order.
                  By default, it is equal to (nb_channels:-1:(nb_channels/2))
computeClassLat*: vector, containing all the class tag in which you want
                  to compute the latency correction. By default, it
                  computes it for all classes but it could be long (for
                  instance you can skip the non-target).
       Weights*: Default: true.
                 option1(given) [nb epochs x1] vector, containing the weights for each
                  epoch if it is computed from an external function.
                 option2 (true/false) boolean. If true (default) the ACSTP compute the
                  weight for each epoch. If false, the weights are
                  desactivated (i.e. set to 1).
       DISPLAY*: Boolean, should the comparative result between the arithmetic ensemble
                  average and the ACSTP should be display at the end. Default: true.

ACSTPstruct is a structure with

             EA: the ensemble average before ACSTP
         EAcstp: the ensemble average corrected with latencies, weighted
                  and filtered + with the effect of overlapping
                  correction
    As Bs Bt At: such as Xhat(:,:,k)=As{indClass}*Bs{indClass}'*W(k)*X(:,:,k)*Bt{indClass}*At{indClass}'
                  Each filter is a cell containing a matrix filter for
                  each class
          Class: The tag and the order in which the filter are sorted
         BestPz: Orders of the best subspace for the ACSTP for the given
                 Class
        Weights: [nb epochs x1] the weights of each epoch
        Latency: [nb epochs x1] the corrected offset of each epoch
     Epoch_size: scalar, the length of the epoch window (in samples)

associated publications

  • L. Korczowski, M. Congedo and C. Jutten, "Single-trial classification of multi-user P300-based Brain-Computer Interface using riemannian geometry," 2015 37th Annual International Conference of the IEEE Engineering in Medicine and Biology Society (EMBC), Milan, 2015, pp. 1769-1772.
  • Louis Korczowski. Méthodes pour l'électroencéphalographie multi-sujet et application aux interfaces cerveau-ordinateur. Traitement du signal et de l'image [eess.SP]. Université Grenoble Alpes, 2018. Français. ⟨NNT : 2018GREAT078⟩. ⟨tel-01961434v4⟩
  • Marco Congedo, Louis Korczowski, Arnaud Delorme, Fernando Lopes da Silva. Spatio-temporal common pattern: A companion method for ERP analysis in the time domain. Journal of Neuroscience Methods, Elsevier, 2016, 267, pp.74-88. ⟨10.1016/j.jneumeth.2016.04.008⟩. ⟨hal-01343026⟩
  • Louis Korczowski, Florent Bouchard, Christian Jutten, Marco Congedo. Mining the Bilinear Structure of Data with Approximate Joint Diagonalization. 24th European Signal Processing Conference (EUSIPCO 2016), EURASIP, Aug 2016, Budapest, Hungary. pp.667-671. ⟨hal-01357245⟩
  • Florent Bouchard, Louis Korczowski, Jérôme Malick, Marco Congedo. Approximate Joint Diagonalization within the Riemannian Geometry Framework. 24th European Signal Processing Conference (EUSIPCO 2016), Aug 2016, Budapest, Hungary. pp.210-214, ⟨10.1109/EUSIPCO.2016.7760240⟩. ⟨hal-01370052
  • Louis Korczowski, Alexandre Barachant, Anton Andreev, Christian Jutten, Marco Congedo. ”BrainInvaders 2” : an open source Plug & Play multi-user BCI videogame. 6th International Brain-Computer Interface Meeting (BCI Meeting 2016), BCI Society, May 2016, Pacific Grove, CA, UnitedStates. pp.10.3217/978-3-85125-467-9, �10.3217/978-3-85125-467-9-224�. �hal-

gipseeg's People

Contributors

lkorczowski avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

gipseeg's Issues

apply supper covariance (bci competition 3 dataset2 p300 speller)

1. > clc;
2. > 
3. > clear;
4. > close all;
5. > 
6. > 
7. > 
8. > TargetChar=[];
9. > StimulusType=[];
10. > 
11. > load 'Subject_A_Train.mat' % load data file
12. > window=160; % window after stimulus (1s)
13. > Signal1=double(Signal);
14. > number_train=1;
15. > 
16. > 
17. > % convert to double precision
18. > Signal1=double(Signal);
19. > Signal2=  Signal1(:,:,[11 34 48 51 54 56 60 2 6 9 13]);
20. > % Signal2=  Signal1(:,:,:);
21. > 
22. > Flashing=double(Flashing);
23. > StimulusCode=double(StimulusCode);
24. > StimulusType=double(StimulusType);
25. > 
26. > 
27. > 
28. > %% digital filtering
29. > N = 7794  ; f1 = 0.1  ; f2 = 10  ; Fs = 240 ;
30. > K1 = round((N*f1)/Fs)  ;    K2 = round((N*f2)/Fs) ;
31. > cc=11;
32. > FFT_X = fft(Signal2, [], 2);
33. > Filterd_FFT_X = zeros(85 , 7794 , cc);
34. > Filterd_FFT_X(: ,[K1:K2 , N-K2:N-K1] ,: ) = FFT_X (: , [K1:K2 , N-K2:N-K1] , : );
35. > Filterd_X = ifft(Filterd_FFT_X , [] , 2 ,'symmetric');
36. > Signal1=Filterd_X;
37. > %%
38. > 
39. > g=50;
40. > % for each character epoch
41. > b=0;
42. > for epoch=1:g   
43. >     epoch
44. >     % get reponse samples at start of each Flash
45. >     for n=2:size(Signal1,2)
46. >         if Flashing(epoch,n)==0 & Flashing(epoch,n-1)==1
47. >             b=b+1;
48. >             rowcol=StimulusCode(epoch,n-1); %%inja mifahmeh kodam satro sotoon toshan shode faghat
49. >             responses(:,:,b)=Signal1(epoch,n-24:n+window-25,:);  %%signal bad az har tahriko joda
50. >             if isempty(StimulusType)==0
51. >                 label(b,:)=unique(StimulusCode(epoch,n-1).*StimulusType(epoch,n-1));
52. >                 if label(b,1)~= 0
53. >                     label(b,1)=1;
54. >                 end
55. >             end
56. >             
57. >         end
58. >     end
59. >     
60. > end
61. > 
62. > X_train2= responses;
63. > xx = permute(X_train2 , [3 , 1 , 2]);   %Rearrange dimensions of N-D array  %%%180*g*160*11
64. > % X_train4 = reshape( xx, 180*g , 160*cc) ;
65. >  
66. > X_trains= X_train4;
67. > 
68. > %%% ebteda class ha ra joda kardam ta supper covariance besazam %%%%
69. > c=0;
70. > b=0;
71. > for i = 1:size(X_trains,1)
72. >     if label(i,:)==1
73. >         b=b+1;
74. >         x1(b,:,:)=X_trains(i,:,:);
75. >     else
76. >         c=c+1;
77. >         x2(c,:,:)=X_trains(i,:,:);
78. >     end
79. >     
80. > end
81. > 
82. > %% apply super cov
83. > 
84. > x1_mean = mean(x1,1);
85. > x1_mean = squeeze(x1_mean);
86. > 
87. > x2_mean = mean(x2,1);
88. > x2_mean = squeeze(x2_mean);
89. > %class1 for each trial
90. > for i_sup = 1 : size(x1,1)
91. >     i_sup
92. >     X_1 =squeeze( x1(i_sup,:,:));
93. >    XRAW_mean1 = [x1_mean';X_1'];
94. >    XRAW_mean11(i_sup,:,:) = cov(XRAW_mean1');
95. > end
96. > %class2 for each trial
97. > for i_sup = 1 : size(x2,1)
98. >     i_sup
99. >     X_2 =squeeze( x2(i_sup,:,:));
100. >    XRAW_mean2 = [x2_mean';X_2'];
101. >    XRAW_mean22(i_sup,:,:) = cov(XRAW_mean2');
102. > end
103. > 
104. > x_new_sup = cat(1,XRAW_mean11,XRAW_mean22);   % new response
105. > 
106. > X_train_sup= x_new_sup;
107. > xx_sup = permute(X_train_sup , [3 , 1 , 2]);
108. > X_train4_sup = reshape( xx_sup, 180*g , 4*cc*cc) ;
109. > 
110. > for d=1:size(X_train4_sup,1)
111. > dec_X_train_sup(d,:) = downsample( X_train4_sup(d,:) , 10);
112. > end
113. > 
114. >  for d=1:size(xx,1)
115. > dec_X_train_sup(d,:,:) = downsample( X_train4_sup(d,:) , 10);
116. >  end
117. > X_trains_sup= dec_X_train_sup;
118. > 
119. > c=0;
120. > b=0;
121. > for i = 1:size(X_trains_sup,1)
122. >     if label(i,:)==1
123. >         b=b+1;
124. >         x1_sup(b,:)=X_trains_sup(i,:);
125. >     else
126. >         c=c+1;
127. >         x2_sup(c,:)=X_trains_sup(i,:);
128. >     end
129. >     
130. > end
131. > 
132. > 
133. > 
134. > c=size(x2_sup,1);
135. > x_tr11_sup = [x1_sup; x1_sup ; x2_sup ;x1_sup ; x1_sup; x1_sup];
136. > c1= size(x1_sup,1);
137. > label1= ones(c1,1);
138. > label2= zeros(c,1);
139. > labeltr_sup = [label1; label1; label2 ; label1 ; label1  ; label1 ];
140. > 
141. > %% LDA train
142. > ldamodel1 = fitcdiscr(x_tr11_sup,labeltr_sup);
143. > %% SVM train
144. > SVMModel= fitcsvm(x_tr11_sup,labeltr_sup,'Standardize',...
145. >     true,'KernelFunction','rbf','BoxConstraint',5, 'KernelScale',20);
146. > 
147. >  %%
148. >  
149. > %%%%%%%%%%% test %%%%%%%%
150. > 
151. > Signal1 = Filterd_X(51:85,:,:);
152. > 
153. > screen = char('A','B','C','D','E','F',...
154. >     'G','H','I','J','K','L',...
155. >     'M','N','O','P','Q','R',...
156. >     'S','T','U','V','W','X',...
157. >     'Y','Z','1','2','3','4',...
158. >     '5','6','7','8','9','_');
159. > 
160. > b=0;
161. > t=35; %% TEDAD CHAR TEST
162. > event=[];
163. > t1=0;
164. > for epoch=51:85
165. >  %%%%%% event
166. >  t1=t1+1;
167. >     h(1)=0;
168. >     l=0;
169. >     for i=2:size(StimulusCode(epoch,:),2)
170. >         h(i)=StimulusCode(1,i);
171. >         if h(i)~= h(i-1) && h(i)~=0             
172. >             l=l+1;
173. >             eventtest(t1,l)=StimulusCode(epoch,i);          
174. >         end
175. >     end
176. >      %%%%%%%%
177. >     for n=2:size(Signal1,2)
178. >         if Flashing(epoch,n)==0 & Flashing(epoch,n-1)==1
179. >             b=b+1;
180. >             rowcol=StimulusCode(epoch,n-1); 
181. >             responsestest(:,:,b)=Signal1(t1,n-24:n+window-25,:); 
182. >            
183. >         end
184. >     end
185. > end
186. > 
187. > 
188. > X_testsa= responsestest;
189. > xtt = permute(X_testsa , [3 , 1 , 2]);   %Rearrange dimensions of N-D array  %%%180*g*160*11
190. > 
191. > x3_mean = mean(xtt,1);
192. > x3_mean = squeeze(x3_mean);
193. > 
194. > for i_sup = 1 : size(X_testsa,3)
195. >     i_sup
196. >     X_3 =squeeze( xtt(i_sup,:,:));
197. >    XRAW_mean3 = [x3_mean';X_3'];
198. >    XRAW_mean33(i_sup,:,:) = cov(XRAW_mean3');
199. > end
200. > 
201. > X_testsa_sup= XRAW_mean33;
202. > % xtt_sup = permute(X_testsa_sup , [3 , 1 , 2]);   %Rearrange dimensions of N-D array  %%%180*g*160*11
203. > X_testsa_sup = reshape(X_testsa_sup, 12*15*t , 4*cc*cc) ;
204. > % 
205. > for d=1:size(X_testsa_sup,1)
206. > dec_X_test_sup(d,:) = downsample( X_testsa_sup(d,:) , 10);
207. > end
208. > 
209. > X_testsa_supper = dec_X_test_sup  ;
210. > 
211. > [aa1,classified_train1 ]= predict(ldamodel1,X_testsa_supper);
212. > Score_pos1 = classified_train1(:,2);
213. > Score_pos1 = normalize(Score_pos1);
214. > 
215. > Score_pos=Score_pos1;
216. > for i=1:t
217. >     for j=1:12
218. >         c=find(eventtest(i,:)==j);
219. >         mean_scor((i-1)*12+j) = mean(Score_pos(180*(i-1)+c));  %%%barasase j chideh
220. >     end
221. > end
222. > 
223. > %% target detection
224. > for k = 1:2*t
225. >     [~ , ind(k)] = max(mean_scor((k-1)*6+1:(k*6)));
226. > end
227. > 
228. > col = ind(1:2:end)';
229. > row = ind(2:2:end)';
230. > row_col = col+(row-1)*6;
231. > target_predict = screen(row_col);
232. > test_str = TargetChar(51:85);
233. > target_ACC = sum(test_str(1:t) == target_predict')/length(target_predict);
234. > disp(target_ACC)
235. > 
236. > %%
237. > %%
238. > [SVMlabel,SVMscoresvm] = predict(SVMModel,X_testsa_supper);
239. > score_target=SVMscoresvm(:,2);
240. > 
241. > % sadafscore=SVMscores;
242. > % sadaflabel=SVMlabel;
243. > 
244. > 
245. > Score_possvm = SVMscoresvm(:,2);
246. > 
247. > for i=1:t
248. >     for j=1:12
249. >         c=find(eventtest(i,:)==j);
250. >         mean_scorsvm((i-1)*12+j) = mean(Score_possvm(180*(i-1)+c));  %%%barasase j chideh
251. >     end
252. > end
253. > 
254. > %% target detection
255. > for k = 1:2*t
256. >     [~ , ind(k)] = max(mean_scorsvm((k-1)*6+1:(k*6)));
257. > end
258. > 
259. > col = ind(1:2:end)';
260. > row = ind(2:2:end)';
261. > row_col = col+(row-1)*6;
262. > target_predictsvm = screen(row_col);
263. > 
264. > target_ACCsvm = sum(test_str(1:t) == target_predictsvm')/length(target_predictsvm);
265. > disp(target_ACCsvm)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.