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.m 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 = 'monkeyF';
  8. datadir_gen = '\';
  9. temp_folder = '\_temps\';
  10. dates = {'20240112','20240115','20240116','20240118'};
  11. instances = 1:2;
  12. hubs = 1:2;
  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. tb =-pre_trial*1000:1:(post_trial)*1000;
  30. instance_chns = 1:256:256*4;
  31. load('\\vs03\vs03-vandc-1\Latents\Passive_Fixation\monkeyN\_logs\1024chns_mapping_20220105.mat')
  32. restarted = 0;
  33. get_diode = 1;
  34. for day = 1:length(dates)
  35. clear datadir all_folders blocks
  36. datadir = [datadir_gen,monkey,'\',dates{day},'\'];
  37. disp(['%%%%%% DAY: ',num2str(day),' ...']);
  38. all_folders = dir(datadir);
  39. all_folders = all_folders([all_folders(:).isdir]);
  40. all_folders = all_folders(~ismember({all_folders(:).name},{'.','..'}));
  41. blocks = length(all_folders);
  42. for b = 1:blocks
  43. block_number = str2num(all_folders(b).name(7:end));
  44. tic
  45. disp(['%%% Block: ',num2str(block_number),' ...']);
  46. % load and group the logs
  47. % MAT files are: [#trial #train_pic #test_pic #pic_rep #ncount #correct]
  48. % ALLMAT files will be: [#trial #train_pic #test_pic #pic_rep #ncount #block #day]
  49. clear MAT temp_MAT
  50. load([datadir_gen,monkey,'\_logs\',log_prefix,monkey,'_',dates{day},'_B',num2str(block_number),'.mat'],'MAT')
  51. temp_MAT = MAT(MAT(:,end)>0,1:5);
  52. temp_MAT = [temp_MAT ones([length(temp_MAT) 1])*block_number];
  53. temp_MAT = [temp_MAT ones([length(temp_MAT) 1])*day];
  54. save([datadir_gen,monkey,temp_folder,'TEMP_MAT_',dates{day},'_B',num2str(block_number),'.mat'],'temp_MAT');
  55. for instance_idx = instances
  56. clear instance_name
  57. instance_name = ['-instance',num2str(instance_idx),'_B',sprintf('%03.0f', block_number)];
  58. for hub_idx = hubs
  59. clear partition_idx partition_name
  60. partition_idx = hub_idx+2*(instance_idx-1);
  61. partition_name = ['partition',num2str(partition_idx),'_B',sprintf('%03.0f', block_number)];
  62. if ~isfile([datadir_gen,monkey,temp_folder,'TEMP_MUA_',dates{day},'_',partition_name,'.mat'])
  63. if hub_idx == 1 || restarted
  64. get_diode = 1;
  65. else
  66. get_diode = 0;
  67. end
  68. % get the difference between the diode and the stimulus bit
  69. if get_diode == 1
  70. clear instance_NS6_filename RAW
  71. instance_NS6_filename = [datadir,'Block_',num2str(block_number),'\NSP',instance_name,'.ns6'];
  72. RAW = openNSx(instance_NS6_filename);
  73. if RAW.RawData.PausedFile==1
  74. RAW.Data = cell2mat(RAW.Data);
  75. end
  76. clear temp temp_trials idx_temp Trials
  77. temp = smooth(double(RAW.Data(1,:)),100);
  78. temp_trials = 1+find(diff(temp)>300);
  79. idx_temp = [1; diff(temp_trials)>Fs/200];
  80. Trials = temp_trials(idx_temp>0);
  81. assert(length(Trials)==length(MAT),'There are (%d) recorded trials while (%d) trails were logged',length(Trials),length(MAT));
  82. clear diode dio_onset
  83. diode = RAW.Data(15,:);
  84. for trl=1:length(Trials)
  85. clear diode_trl
  86. temp_int = Trials(trl):Trials(trl)+Fs*trial_length-1;
  87. diode_trl=diode(temp_int);
  88. f=find(abs(diode_trl)>1*10^4,1,'first');
  89. if isempty(f)
  90. dio_onset(trl) = 0;
  91. else
  92. dio_onset(trl)= f;
  93. end
  94. end
  95. restarted = 0;
  96. end
  97. % load the raw data
  98. clear instance_NS6_filename RAW temp_block_mua
  99. instance_NS6_filename = [datadir,'Block_',num2str(block_number),'\Hub',num2str(hub_idx),instance_name,'.ns6'];
  100. RAW = openNSx(instance_NS6_filename);
  101. if RAW.RawData.PausedFile==1
  102. RAW.Data = cell2mat(RAW.Data);
  103. end
  104. temp_block_mua = nan([256 length(temp_MAT) length(tb)]);
  105. for chn = 1:256
  106. clear S dum1 dum2
  107. S=double(squeeze(RAW.Data(chn,:)))';
  108. % bandpass
  109. dum1 = filtfilt(B, A, S); % apply filter to the data
  110. % rectify
  111. dum2 = abs(dum1);
  112. % low-pass
  113. clear muafilt
  114. muafilt = filtfilt(D, C, dum2);
  115. % remove 50Hz line noise (+ harmonics)
  116. buttLoop = muafilt;
  117. for i = 1:5
  118. d = designfilt('bandstopiir','FilterOrder',2, ...
  119. 'HalfPowerFrequency1',50*i-5,'HalfPowerFrequency2',50*i+5, ...
  120. 'DesignMethod','butter','SampleRate',Fs);
  121. buttLoop = filtfilt(d,buttLoop);
  122. end
  123. % remove 60Hz screen refresh rate (+ harmonics)
  124. for i = 1:5
  125. d = designfilt('bandstopiir','FilterOrder',2, ...
  126. 'HalfPowerFrequency1',60*i-5,'HalfPowerFrequency2',60*i+5, ...
  127. 'DesignMethod','butter','SampleRate',Fs);
  128. buttLoop = filtfilt(d,buttLoop);
  129. end
  130. muafilt = buttLoop';
  131. % select only correct trials and downsample
  132. clear temp_chn
  133. temp_chn = nan([length(temp_MAT) length(tb)]);
  134. z = 1;
  135. for trl=1:length(Trials)
  136. if MAT(trl,end)>0
  137. clear temp_int temp_data
  138. temp_int = Trials(trl)+dio_onset(trl)-Fs*pre_trial:Trials(trl)+dio_onset(trl)+Fs*post_trial-1;
  139. temp_chn(z,:) = downsample(muafilt(temp_int),downsample_factor);
  140. z=z+1;
  141. end
  142. end
  143. temp_block_mua(chn,:,:) = temp_chn;
  144. end
  145. if plot_avg
  146. plot(squeeze(nanmean(temp_block_mua,[1,2])));
  147. end
  148. clear mapping_inst
  149. mapping_inst = mapping(instance_chns(instance_idx):instance_chns(instance_idx)+256-1);
  150. mapping_inst = mapping_inst-((instance_idx-1)*256);
  151. temp_block_mua = temp_block_mua(mapping_inst,:,:);
  152. % store temps
  153. save([datadir_gen,monkey,temp_folder,'TEMP_MUA_',dates{day},'_',partition_name,'.mat'],'temp_block_mua','-v7.3');
  154. pause(5)
  155. disp(['% (Partiton: ',num2str(partition_name),' done!)']);
  156. else
  157. restarted = 1;
  158. end
  159. disp(['%%% ... done in: ',num2str(round(toc)),'s'])
  160. end
  161. end
  162. end
  163. end