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.

getDS.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. %detect putative dentate spikes, extract their features and voltage profiles
  2. %2021 Dino Dvorak, New York University, neuraldino@gmail.com
  3. %Dentate spikes and external control of hippocampal function,
  4. %Cell Reports, Volume 36, Issue 5, 2021,109497,ISSN 2211-1247,
  5. %https://doi.org/10.1016/j.celrep.2021.109497
  6. clear; close all; clc;
  7. eegFS = 2000; %sample rate
  8. %input LFP file (channels x samples)
  9. fnEEG = '2016_09_30_PP12_334_PRETRAIN_BASE_eeg.mat';
  10. %DG channel (found using initial visual inspection)
  11. chDG = 24;
  12. %directories
  13. drMAT = 'MAT_EEG/'; %LFPs
  14. drOUT = 'DS/'; %OUTPUT
  15. %create filter for detection
  16. %pass-band 5-100Hz, 4Hz transition band, 40Hz attenuation
  17. [b, gd] = getFIRbandpass( 5,100,4,40,eegFS );
  18. chAround = 5; %+/- channels around for DS profile
  19. winBA = [60 20]; %search window for maxima before/after in samples (-60..-20samples or +20..+60 samples)
  20. thMin = []; %smallest threshold to accept (saves data)
  21. %features
  22. labelsFeat = {'sample','promZ','peakZ','peakRaw','promZbefore','promZafter',... %1..6
  23. 'peakZbefore','peakZafter','minZbefore','minZafter',...%7..10
  24. 'wDG','wBA','w50','tB','tA','tminB','tminA','acc','speed','max10_30before','max10_30after'}; %11..21
  25. %load LFP
  26. load([drMAT fnEEG]);
  27. eegData = double(eegData);
  28. Nchannels = size(eegData,1);
  29. %DG electrode
  30. eegDG = eegData(chDG,:);
  31. %filter 2-100Hz
  32. chST = chDG - chAround;
  33. chED = chDG + chAround;
  34. if chED > Nchannels; chED = Nchannels; end;
  35. if chST < 1; chST = 1; end;
  36. channelsProfiles = chST:chED;
  37. chDGk = find(channelsProfiles == chDG);
  38. eegF = filter(b,1,eegData(chST:chED,:),[],2);
  39. eegF = cat(2,eegF(:,gd+1:end),zeros(size(eegF,1),gd));
  40. %DG channel
  41. eegFDG = eegF(chDGk,:);
  42. %DG - maxima and minima (extract width,prominence)
  43. [MaxesDG,kMaxesDG,wDG,pDG] = findpeaks(eegFDG);
  44. [~,kMinsDG] = findpeaks(1.01*max(eegFDG) - eegFDG);
  45. %for each maxima in DG
  46. feat = nan(length(kMaxesDG),23);
  47. for i = 10:length(kMaxesDG)-10 %skip first couple of minima for before/after min-max computations
  48. s = kMaxesDG(i); %sample
  49. pDGi = pDG(i); %prominence of peak in z-score signal
  50. wDGi = wDG(i)/eegFS*1000; %width of peak in z-score signal
  51. pDGB = pDG(i-1); %prominence of peak before in z-score signal
  52. pDGA = pDG(i+1); %prominence of peak after in z-score signal
  53. tDGB = (s - kMaxesDG(i-1))/eegFS*1000; %mseconds to maxima before
  54. tDGA = (kMaxesDG(i+1) - s)/eegFS*1000; %mseconds to maxima after
  55. mDG = MaxesDG(i); %max value in z-scored filtered signal
  56. acci = nan; %acceleration
  57. mDGB = MaxesDG(i-1); %preceding maxima in z-scored filtered signal
  58. mDGA = MaxesDG(i+1); %following maxima in z-scored filtered signal
  59. %indexes preceeding and following minima
  60. kB = kMinsDG(kMinsDG < s);
  61. kA = kMinsDG(kMinsDG > s);
  62. if isempty(kB) || isempty(kA); continue; end;
  63. kB = kB(end);
  64. kA = kA(1);
  65. %time to minima before
  66. tmB = (s - kB)/eegFS*1000; %mseconds to minima before
  67. tmA = (kA - s)/eegFS*1000; %mseconds to minima after
  68. %maxima in raw signal
  69. mr = max(eegDG(s-10:s+10));
  70. %peak to to minima before and after
  71. mB = eegFDG(kB);
  72. mA = eegFDG(kA);
  73. %speed
  74. spi = nan;
  75. %width between minima
  76. wBA = (kA-kB)/eegFS*1000;
  77. %width 50%
  78. w50 = nan;
  79. k50B = nan;
  80. k50A = nan;
  81. if mB > mA %before higher
  82. level = (mDG + mB)/2;
  83. else %after higher
  84. level = (mDG + mA)/2;
  85. end
  86. x = eegFDG(kB:kA);
  87. %cut before maxima
  88. k = find(x(1:end-1) <= level & x(2:end) > level);
  89. if ~isempty(k)
  90. k50B = k(1);
  91. end
  92. %cut after maxima
  93. k = find(x(1:end-1) >= level & x(2:end) < level);
  94. if ~isempty(k)
  95. k50A = k(end);
  96. end
  97. if ~isnan(k50B) && ~isnan(k50A)
  98. w50 = (k50A-k50B)/eegFS*1000;
  99. end
  100. %winBA = [60 20];
  101. %maxima before
  102. x = eegFDG(s-winBA(1):s-winBA(2));
  103. maxB = max(x);
  104. %maxima after
  105. x = eegFDG(s+winBA(2):s+winBA(1));
  106. maxA = max(x);
  107. %minima in raw before
  108. mrB = min(eegDG(kB-10:kB+10));
  109. %minima in raw after
  110. mrA = min(eegDG(kA-10:kA+10));
  111. feat(i,1) = s; %sample max sDG
  112. feat(i,2) = pDGi; %prominence of peak in z-score signal
  113. feat(i,3) = mDG; %max value in z-scored filtered signal
  114. feat(i,4) = mr; %maxima in raw
  115. feat(i,5) = pDGB; %prominence of peak before in z-score signal
  116. feat(i,6) = pDGA; %prominence of peak after in z-score signal
  117. feat(i,7) = mDGB; %preceding maxima in z-scored filtered signal
  118. feat(i,8) = mDGA; %following maxima in z-scored filtered signal
  119. feat(i,9) = mB; %minima preceding peak in z-score signal
  120. feat(i,10) = mA; %minima following peak in z-score signal
  121. feat(i,11) = wDGi; %width of peak in z-score signal
  122. feat(i,12) = wBA; %width between minima
  123. feat(i,13) = w50; %width 50%
  124. feat(i,14) = tDGB; %mseconds to maxima before
  125. feat(i,15) = tDGA; %mseconds to maxima after
  126. feat(i,16) = tmB; %mseconds to minima before
  127. feat(i,17) = tmA; %mseconds to minima after
  128. feat(i,18) = acci; %acceleration
  129. feat(i,19) = spi; %speed
  130. feat(i,20) = maxB; %maxima 30-10ms before
  131. feat(i,21) = maxA; %maxima 10-30ms after
  132. feat(i,22) = mrB; %minima in raw before
  133. feat(i,23) = mrA; %minima in raw after
  134. end
  135. %remove nans
  136. knan = ~isnan(feat(:,1));
  137. feat = feat(knan,:);
  138. %apply thMin
  139. if ~isempty(thMin)
  140. k = feat(:,3) > thMin;
  141. %d = feat(:,3) - feat(:,9); %dist peak to minima before
  142. %k = d > 2;
  143. feat = feat(k,:);
  144. end
  145. %extract profiles around maxima
  146. s = feat(:,1); %samples;
  147. profilesDS = eegF(:,s);
  148. %save putative DS events
  149. save([drOUT fnEEG],'feat','chDG','profilesDS','channelsProfiles','labelsFeat');
  150. %plot output
  151. figure;
  152. subplot(1,2,1);
  153. plot(mean(profilesDS,2),1:size(profilesDS,1))
  154. title('Volrage DS profile');
  155. subplot(1,2,2);
  156. histogram(feat(:,11));
  157. title('Event width');