Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

extract_MUA_v2_N.m 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. %%% extact MUA - THINGS
  2. % v.2-Gemini
  3. % 2024 P. Papale fecit
  4. clear all
  5. addpath(genpath('\_code\code_utils_v2\'));
  6. % constants
  7. monkey = 'monkeyN';
  8. datadir_gen = '\';
  9. temp_folder = '\_temps\';
  10. dates = {'20220111','20220112','20220113','20220114'};
  11. instances = 1:8;
  12. stimbit = 1;
  13. trial_length = .3;
  14. pre_trial = .1;
  15. post_trial = trial_length-pre_trial;
  16. log_prefix = 'THINGS_';
  17. plot_avg = 1;
  18. %
  19. downsample_factor = 30;
  20. Fs = 30000;
  21. Fbp=[500,5000];
  22. N = 2; % filter order
  23. Fn = Fs/2; % Nyquist frequency
  24. Fl=200;
  25. % FsD = Fs/downsample_factor;
  26. % FnD = FsD/2; % Downsampled Nyquist frequency
  27. [B, A] = butter(N, [min(Fbp)/Fn max(Fbp)/Fn]); % compute filter coefficients
  28. [D, C] = butter(N,Fl/Fn,'low'); % compute filter coefficients
  29. [F, E] = butter(N,[(50-5)/Fn (50+5)/Fn],'stop'); % compute filter coefficients
  30. for i = 1:5
  31. d50{i} = designfilt('bandstopiir','FilterOrder',2, ...
  32. 'HalfPowerFrequency1',50*i-5,'HalfPowerFrequency2',50*i+5, ...
  33. 'DesignMethod','butter','SampleRate',Fs);
  34. end
  35. for i = 1:5
  36. d60{i} = designfilt('bandstopiir','FilterOrder',2, ...
  37. 'HalfPowerFrequency1',60*i-5,'HalfPowerFrequency2',60*i+5, ...
  38. 'DesignMethod','butter','SampleRate',Fs);
  39. end
  40. tb =-pre_trial*1000:1:(post_trial)*1000;
  41. instance_chns = 1:128:128*length(instances);
  42. load('\\vs03\vs03-vandc-1\Latents\Passive_Fixation\monkeyN\_logs\1024chns_mapping_20220105.mat')
  43. restarted = 0;
  44. get_diode = 1;
  45. for day = 1:length(dates)
  46. clear datadir all_folders blocks
  47. datadir = [datadir_gen,monkey,'\',dates{day},'\'];
  48. disp(['%%%%%% DAY: ',num2str(day),' ...']);
  49. all_folders = dir(datadir);
  50. all_folders = all_folders([all_folders(:).isdir]);
  51. all_folders = all_folders(~ismember({all_folders(:).name},{'.','..'}));
  52. blocks = length(all_folders);
  53. for b = 1:blocks
  54. block_number = str2num(all_folders(b).name(7:end));
  55. tic
  56. disp(['%%% Block: ',num2str(block_number),' ...']);
  57. % load and group the logs
  58. % MAT files are: [#trial #train_pic #test_pic #pic_rep #ncount #correct]
  59. % ALLMAT files will be: [#trial #train_pic #test_pic #pic_rep #ncount #day]
  60. clear MAT temp_MAT
  61. load([datadir_gen,monkey,'\_logs\',log_prefix,monkey,'_',dates{day},'_B',num2str(block_number),'.mat'],'MAT')
  62. temp_MAT = MAT(MAT(:,end)>0,1:5);
  63. temp_MAT = [temp_MAT ones([length(temp_MAT) 1])*day];
  64. save([datadir_gen,monkey,temp_folder,'TEMP_MAT_',dates{day},'_B',num2str(block_number),'.mat'],'temp_MAT');
  65. for instance_idx = instances
  66. clear instance_name
  67. instance_name = ['instance',num2str(instance_idx),'_B',sprintf('%03.0f', block_number)];
  68. clear partition_idx partition_name
  69. partition_idx = instance_idx;
  70. partition_name = ['partition',num2str(partition_idx),'_B',sprintf('%03.0f', block_number)];
  71. if ~isfile([datadir_gen,monkey,temp_folder,'TEMP_MUA_',dates{day},'_',partition_name,'.mat'])
  72. if instance_idx == 1 || restarted
  73. get_diode = 1;
  74. else
  75. get_diode = 0;
  76. end
  77. % load the raw data
  78. clear instance_NS6_filename RAW
  79. instance_NS6_filename = [datadir,'Block_',num2str(block_number),'\',instance_name,'.ns6'];
  80. RAW = openNSx(instance_NS6_filename);
  81. if RAW.RawData.PausedFile==1
  82. RAW.Data = cell2mat(RAW.Data);
  83. end
  84. % load the stored events
  85. clear instance_NEV_filename EVENT Trials_idxs Trials
  86. instance_NEV_filename = [datadir,'Block_',num2str(block_number),'\',instance_name,'.nev'];
  87. EVENT = openNEV(instance_NEV_filename,'nosave','noread');
  88. Trials_idxs=find(EVENT.Data.SerialDigitalIO.UnparsedData==2^stimbit);%starts at 2^0, till 2^7
  89. Trials=EVENT.Data.SerialDigitalIO.TimeStamp(Trials_idxs);%time stamps corresponding to stimulus onset
  90. assert(length(Trials)==length(MAT),'There are (%d) recorded trials while (%d) trails were logged',length(Trials),length(MAT));
  91. % get the difference between the diode and the stimulus bit
  92. if get_diode == 1
  93. clear diode dio_onset
  94. if instance_idx ~=1
  95. % load the raw data
  96. clear temp_instance_name temp_RAW
  97. temp_instance_name = ['instance',num2str(1),'_B',sprintf('%03.0f', block_number)];
  98. instance_NS6_filename = [datadir,'Block_',num2str(block_number),'\',temp_instance_name,'.ns6'];
  99. temp_RAW = openNSx(instance_NS6_filename);
  100. if temp_RAW.RawData.PausedFile==1
  101. temp_RAW.Data = cell2mat(temp_RAW.Data);
  102. end
  103. clear temp_instance_NEV_filename temp_EVENT temp_Trials_idxs temp_Trials
  104. temp_instance_NEV_filename = [datadir,'Block_',num2str(block_number),'\',instance_name,'.nev'];
  105. temp_EVENT = openNEV(temp_instance_NEV_filename,'nosave','noread');
  106. temp_Trials_idxs=find(temp_EVENT.Data.SerialDigitalIO.UnparsedData==2^stimbit);%starts at 2^0, till 2^7
  107. temp_Trials=temp_EVENT.Data.SerialDigitalIO.TimeStamp(temp_Trials_idxs);%time stamps corresponding to stimulus onset
  108. diode = temp_RAW.Data(143,:);
  109. clear temp_RAW
  110. else
  111. diode = RAW.Data(143,:);
  112. temp_Trials = Trials;
  113. end
  114. for trl=1:length(temp_Trials)
  115. clear diode_trl
  116. temp_int = temp_Trials(trl):temp_Trials(trl)+Fs*trial_length-1;
  117. diode_trl=diode(temp_int);
  118. f=find(abs(diode_trl)>1*10^4,1,'first');
  119. if isempty(f)
  120. dio_onset(trl) = 0;
  121. else
  122. dio_onset(trl)= f;
  123. end
  124. end
  125. restarted = 0;
  126. end
  127. clear temp_block_mua
  128. temp_block_mua = nan([128 length(temp_MAT) length(tb)]);
  129. for chn = 1:128
  130. clear S dum1 dum2
  131. S=double(squeeze(RAW.Data(chn,:)))';
  132. % bandpass
  133. dum1 = FiltFiltM(B, A, S); % apply filter to the data
  134. % rectify
  135. dum2 = abs(dum1);
  136. % low-pass
  137. clear muafilt
  138. muafilt = FiltFiltM(D, C, dum2);
  139. % remove 50Hz line noise (+ harmonics)
  140. buttLoop = muafilt;
  141. for i = 1:5
  142. % d = designfilt('bandstopiir','FilterOrder',2, ...
  143. % 'HalfPowerFrequency1',50*i-5,'HalfPowerFrequency2',50*i+5, ...
  144. % 'DesignMethod','butter','SampleRate',Fs);
  145. % buttLoop = filtfilt(d,buttLoop);
  146. % buttLoop = filtfilt(d50{i},buttLoop);
  147. [F, E] = butter(N,[(50*i-5)/Fn (50*i+5)/Fn],'stop');
  148. buttLoop = FiltFiltM(F, E, buttLoop);
  149. end
  150. % remove 60Hz screen refresh rate (+ harmonics)
  151. for i = 1:5
  152. % d = designfilt('bandstopiir','FilterOrder',2, ...
  153. % 'HalfPowerFrequency1',60*i-5,'HalfPowerFrequency2',60*i+5, ...
  154. % 'DesignMethod','butter','SampleRate',Fs);
  155. % buttLoop = filtfilt(d,buttLoop);
  156. % buttLoop = filtfilt(d60{i},buttLoop);
  157. [F, E] = butter(N,[(60*i-5)/Fn (60*i+5)/Fn],'stop');
  158. buttLoop = FiltFiltM(F, E, buttLoop);
  159. end
  160. muafilt = buttLoop';
  161. % select only correct trials and downsample
  162. clear temp_chn
  163. temp_chn = nan([length(temp_MAT) length(tb)]);
  164. z = 1;
  165. for trl=1:length(Trials)
  166. if MAT(trl,end)>0
  167. clear temp_int temp_data
  168. temp_int = Trials(trl)+dio_onset(trl)-Fs*pre_trial:Trials(trl)+dio_onset(trl)+Fs*post_trial-1;
  169. temp_chn(z,:) = downsample(muafilt(temp_int),downsample_factor);
  170. z=z+1;
  171. end
  172. end
  173. temp_block_mua(chn,:,:) = temp_chn;
  174. end
  175. if plot_avg
  176. plot(squeeze(nanmean(temp_block_mua,[1,2])));
  177. end
  178. % store temps
  179. clear mapping_inst
  180. mapping_inst = mapping(instance_chns(instance_idx):instance_chns(instance_idx)+128-1);
  181. mapping_inst = mapping_inst-((instance_idx-1)*128);
  182. temp_block_mua = temp_block_mua(mapping_inst,:,:);
  183. save([datadir_gen,monkey,temp_folder,'TEMP_MUA_',dates{day},'_',partition_name,'.mat'],'temp_block_mua','-v7.3');
  184. pause(5)
  185. disp(['% (Partiton: ',num2str(partition_name),' done!)']);
  186. else
  187. restarted = 1;
  188. end
  189. disp(['%%% ... done in: ',num2str(round(toc)),'s'])
  190. end
  191. end
  192. end