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.

DD_Stats.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. %% define some variables
  2. clear
  3. % select dataset
  4. daSeI = 1; % 1: only Low/High; 2: 3/8 and Low/High
  5. anaType = 1; % 1: window-based analysis; 2: point-based analysis
  6. % select test and stat parameter
  7. test = 1; % 1: t-test, 2: ranksum
  8. statParam = 1; % 1: P2P, 2: RMS, 3: AUC
  9. % define time windows to be analysed (in s)
  10. % low
  11. win1L = [0.0027,0.0092]; % ABR (whole)
  12. win2L = [0.005,0.0097]; % ABR (peak 5 only)
  13. % win3L = [0.0045,0.0075]; % ABR (late)
  14. % win4L = [0.006,0.010]; % ABR (omitted); original window ([0.007,0.017]) is too long for 25 ms dataset
  15. % high
  16. win1H = [0.0027,0.0092]; % ABR (whole)
  17. win2H = [0.004,0.008]; % ABR (peak 5 only)
  18. % win3H = [0.0045,0.007]; % ABR (late)
  19. % win4H = [0.0065,0.01]; % ABR (omitted)
  20. winTxt = ["ABR","ABR early","ABR late","Omission Response"];
  21. inclCtrl = 0; % include control data? (0: no, 1: 50Per, 2: MR, 3: DevOnly)
  22. omRespI = 0; % run stats for omission responses? (0: no, 1: yes)
  23. % define number of std-position datasets
  24. switch omRespI
  25. case 0
  26. nSubStd = 2; % 2 for all datasets
  27. case 1
  28. nSubStd = 1; % except Om dataset (which has only std after dev)
  29. end
  30. %% load datasets
  31. % load control data and rename important variables
  32. for repRateI = 1:3 % once for each rep rate dataset
  33. for subStdI = 2:nSubStd % once for each std position dataset
  34. switch inclCtrl
  35. case {0,3} % use different rep rate datasets only if no ctrl or dev only control is included (because there are no control data for 25 and 30 ms)
  36. switch repRateI
  37. case 1
  38. repRate = '25ms';
  39. case 2
  40. repRate = '30ms';
  41. case 3
  42. repRate = '50ms';
  43. end
  44. case {1,2} % if 50Per or MR control is included, only use 50 ms dataset
  45. repRate = '50ms';
  46. end
  47. switch subStdI
  48. case 1
  49. subStd = 'SaD';
  50. case 2
  51. subStd = 'SbD';
  52. end
  53. switch omRespI
  54. case 0
  55. switch inclCtrl
  56. case 1
  57. load(['DD_avData_50Per_',repRate,'_',subStd,'.mat'])
  58. dataAv_cell_Ctrl = dataAv_cell; % rename
  59. fileI_Oddb_cell_Ctrl = fileI_Oddb_cell; % rename
  60. fileI_Ctrl_cell_Ctrl = fileI_Ctrl_cell; % rename
  61. case 2
  62. load(['DD_avData_MR_',repRate,'_',subStd,'.mat'])
  63. dataAv_cell_Ctrl = dataAv_cell; % rename
  64. fileI_Oddb_cell_Ctrl = fileI_Oddb_cell; % rename
  65. fileI_Ctrl_cell_Ctrl = fileI_Ctrl_cell; % rename
  66. case 3
  67. load(['DD_avData_LowOnly_',repRate,'_',subStd,'.mat'])
  68. dataAv_cell_LowOnly = dataAv_cell; % rename
  69. fileI_Oddb_cell_Ctrl = fileI_Oddb_cell; % rename - not necessary to do the same with corresponding "high" file indices, since they should be the same between high and low
  70. fileI_Ctrl_cell_Ctrl = fileI_Ctrl_cell; % rename - not necessary to do the same with corresponding "high" file indices, since they should be the same between high and low
  71. load(['DD_avData_HighOnly_',repRate,'_',subStd,'.mat'])
  72. dataAv_cell_HighOnly = dataAv_cell; % rename
  73. end
  74. % load oddball data
  75. load(['DD_avData_Oddball_',repRate,'_',subStd,'.mat'])
  76. case 1
  77. inclCtrl = 0; % no control for OM data
  78. % load OM data
  79. load(['DD_avData_HighOm_',repRate,'.mat'])
  80. dataAv_cell_HighOm = dataAv_cell; % rename
  81. load(['DD_avData_LowOm_',repRate,'.mat'])
  82. dataAv_cell_LowOm = dataAv_cell; % rename
  83. end
  84. %% do some additional calulations that are required
  85. fs = fs_cell{1}(1);
  86. pts2begin = pts2begin_cell{1}(1);
  87. winAll{1} = round([win1L;win2L]*fs)+pts2begin+round(blcEnd(1)*fs+1); % combine time windows, convert them into points and correct for stim delay (pts2begin) and baseline correction window (blcEnd = stimulus peak)
  88. winAll{2} = round([win1H;win2H]*fs)+pts2begin+round(blcEnd(2)*fs+1);
  89. switch anaType
  90. case 1 % window-based analysis
  91. nSmpl = size(winAll{1},1); % number of windows to be analysed
  92. case 2 % point-based analysis
  93. nSmpl = size(dataAv_cell{1}{1},1); % number of points of each recording
  94. end
  95. nStims = 2; % number of different stimuli per combination
  96. nFilt = nFilt_cell{1};
  97. switch inclCtrl
  98. case 0
  99. switch omRespI
  100. case 0
  101. fileName = 'DD_statsData_noCtrl';
  102. case 1
  103. fileName = 'DD_statsData_Om';
  104. % replace data in dataAv_cell with omission response data
  105. for c = 1:nComb
  106. dataAv_cell{c}{1} = dataAv_cell_HighOm{c}{3};
  107. dataAv_cell{c}{2} = dataAv_cell_HighOm{c}{4};
  108. dataAv_cell{c}{3} = dataAv_cell_LowOm{c}{1};
  109. dataAv_cell{c}{4} = dataAv_cell_LowOm{c}{2};
  110. end
  111. end
  112. nCond = 2; % 2 conditions: dev and std
  113. data = dataAv_cell; % only oddball data
  114. case {1,2,3}
  115. switch inclCtrl
  116. case 1
  117. fileName = 'DD_statsData_50Per';
  118. case 2
  119. fileName = 'DD_statsData_MR';
  120. case 3
  121. fileName = 'DD_statsData_DevO';
  122. end
  123. nCond = 3; % 3 conditions: dev, std and control
  124. data = cell(size(dataAv_cell));
  125. for c = 1:nComb % once for each stimulus combination
  126. if inclCtrl==3 % for DevOnly control
  127. dataAv_cell_Ctrl{c}{1} = dataAv_cell_LowOnly{c}{1}; % assign DevOnly Low data as control of stimulus 1
  128. dataAv_cell_Ctrl{c}{2} = dataAv_cell_HighOnly{c}{3}; % assign DevOnly High data as control of stimulus 2
  129. end
  130. for s = 1:nStims % once for each stimulus frequency
  131. for cn = 1:nCond % once for each stimulus condition (dev, std, ctrl)
  132. switch cn % change dataset depending on condition (Oddball vs. control)
  133. case {1,2} % if oddball
  134. data{c}{(s-1)*nCond+cn} = dataAv_cell{c}{(s-1)*2+cn}(:,fileI_Oddb_cell_Ctrl{c},:); % concatenate oddball data of respective stimulus & condition (dev/std)
  135. case 3 % if control
  136. data{c}{(s-1)*nCond+cn} = dataAv_cell_Ctrl{c}{s}(:,fileI_Ctrl_cell_Ctrl{c},:); % concatenate control data of respective stimulus
  137. end
  138. end
  139. end
  140. end
  141. end
  142. %% calulate statistical variable (trapz, mean V, etc.) for each sample (points or windows)
  143. ampS = cell(1,nComb); % preallocate
  144. ampSNd = cell(1,nComb); % preallocate
  145. maxV = cell(1,nComb); % preallocate
  146. maxI = cell(1,nComb); % preallocate
  147. timS = cell(1,nComb); % preallocate
  148. widS = cell(1,nComb); % preallocate
  149. timSNd = cell(1,nComb); % preallocate
  150. ampCsS = cell(1,nComb); % preallocate
  151. maxCsV = cell(1,nComb); % preallocate
  152. maxCsI = cell(1,nComb); % preallocate
  153. timCsS = cell(1,nComb); % preallocate
  154. ampAvCsS = cell(1,nComb); % preallocate
  155. ampSeCsS = cell(1,nComb); % preallocate
  156. timAvCsS = cell(1,nComb); % preallocate
  157. timSeCsS = cell(1,nComb); % preallocate
  158. ampGrAvCsS = cell(1,nComb); % preallocate
  159. maxGrAvCsV = cell(1,nComb); % preallocate
  160. maxGrAvCsI = cell(1,nComb); % preallocate
  161. timGrAvCsS = cell(1,nComb); % preallocate
  162. for c = 1:nComb % once for each stimulus combination
  163. nFiles = nFiles_cell{c};
  164. ampS{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  165. ampSNd{c} = zeros(nStims,nCond,nFilt,nSmpl); % preallocate
  166. maxV{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  167. maxI{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  168. timS{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  169. widS{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  170. timSNd{c} = zeros(nStims,nCond,nFilt,nSmpl); % preallocate
  171. widSNd{c} = zeros(nStims,nCond,nFilt,nSmpl); % preallocate
  172. ampCsS{c} = zeros(nFiles,nStims,nFilt,nSmpl,nConS); % preallocate
  173. maxCsV{c} = zeros(nFiles,nStims,nFilt,nSmpl,nConS); % preallocate
  174. maxCsI{c} = zeros(nFiles,nStims,nFilt,nSmpl,nConS); % preallocate
  175. timCsS{c} = zeros(nFiles,nStims,nFilt,nSmpl,nConS); % preallocate
  176. ampAvCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  177. ampSeCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  178. timAvCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  179. timSeCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  180. ampGrAvCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  181. maxGrAvCsV{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  182. maxGrAvCsI{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  183. timGrAvCsS{c} = zeros(nStims,nFilt,nSmpl,nConS); % preallocate
  184. pks = zeros(1,nFiles);
  185. locs = zeros(1,nFiles);
  186. w = zeros(1,nFiles);
  187. for s = 1:nStims % once for each stimulus frequency
  188. for cn = 1:nCond % once for each stimulus condition (dev, std, (ctrl))
  189. for ft = 1:nFilt % once for each filter
  190. for sp = 1:nSmpl % once for each sample (windows or points)
  191. switch anaType
  192. case 1
  193. switch statParam
  194. case 1
  195. ampS{c}(:,s,cn,ft,sp) = peak2peak(data{c}{(s-1)*nCond+cn}((winAll{s}(sp,1):winAll{s}(sp,2)),:,ft)); % calculate variable per window
  196. case 2
  197. ampS{c}(:,s,cn,ft,sp) = rms(data{c}{(s-1)*nCond+cn}((winAll{s}(sp,1):winAll{s}(sp,2)),:,ft)); % calculate variable per window
  198. case 3
  199. ampS{c}(:,s,cn,ft,sp) = trapz(abs(data{c}{(s-1)*nCond+cn}((winAll{s}(sp,1):winAll{s}(sp,2)),:,ft))); % calculate variable per window
  200. end
  201. % peak latency and width analysis
  202. for f = 1:nFiles
  203. [pksTemp,locTemp,~,~] = findpeaks(data{c}{(s-1)*nCond+cn}((winAll{s}(sp,1):winAll{s}(sp,2)),f,ft));
  204. [maxV,maxI] = max(pksTemp);
  205. pks(f) = pksTemp(maxI);
  206. locs(f) = locTemp(maxI);
  207. end
  208. timS{c}(:,s,cn,ft,sp) = (locs+(winAll{s}(sp,1)-pts2begin-round(blcEnd(s)*fs+1)))/fs*1000; % convert points to timing
  209. % [maxV{c}(:,s,cn,ft,sp),maxI{c}(:,s,cn,ft,sp)] = max(data{c}{(s-1)*nCond+cn}((winAll{s}(sp,1):winAll{s}(sp,2)),:,ft)); % identify peak and peak index (=timing) per window
  210. % timS{c}(:,s,cn,ft,sp) = (maxI{c}(:,s,cn,ft,sp)+(winAll{s}(sp,1)-pts2begin-round(blcEnd(s)*fs+1)))/fs*1000; % convert points to timing
  211. % test for normality
  212. ampSNd{c}(s,cn,ft,sp) = lillietest(ampS{c}(:,s,cn,ft,sp));
  213. timSNd{c}(s,cn,ft,sp) = lillietest(timS{c}(:,s,cn,ft,sp));
  214. % standard cluster analysis
  215. if cn==1 % only 1 condition exists
  216. for cs = 1:nConS % once for each consecutive std
  217. switch statParam
  218. case 1
  219. ampCsS{c}(:,s,ft,sp,cs) = peak2peak(conSAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,:,cs,ft)); % calculate variable per window
  220. case 2
  221. ampCsS{c}(:,s,ft,sp,cs) = rms(conSAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,:,cs,ft)); % calculate variable per window
  222. case 3
  223. ampCsS{c}(:,s,ft,sp,cs) = trapz(abs(conSAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,:,cs,ft))); % calculate variable per window
  224. end
  225. % peak latency and width analysis
  226. for f = 1:nFiles
  227. [pksTemp,locTemp,~,~] = findpeaks(conSAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,f,cs,ft));
  228. [maxV,maxI] = max(pksTemp);
  229. pks(f) = pksTemp(maxI);
  230. locs(f) = locTemp(maxI);
  231. end
  232. % [maxCsV{c}(:,s,ft,sp,cs),maxCsI{c}(:,s,ft,sp,cs)] = max(conSAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,:,cs,ft)); % identify peak and peak index (=timing) per window
  233. timCsS{c}(:,s,ft,sp,cs) = (locs+(winAll{s}(sp,1)-pts2begin-round(blcEnd(s)*fs+1)))/fs*1000; % convert points to timing
  234. % timCsS{c}(:,s,ft,sp,cs) = maxCsI{c}(:,s,ft,sp,cs)/fs*1000; % convert points to timing
  235. ampAvCsS{c}(s,ft,sp,cs) = mean(ampCsS{c}(:,s,ft,sp,cs),1); % calculate average from values of individual responses
  236. ampStdDCsS = std(ampCsS{c}(:,s,ft,sp,cs),0,1);
  237. ampSeCsS{c}(s,ft,sp,cs) = ampStdDCsS/sqrt(nFiles);
  238. timAvCsS{c}(s,ft,sp,cs) = mean(timCsS{c}(:,s,ft,sp,cs),1);
  239. timStdDCsS = std(timCsS{c}(:,s,ft,sp,cs),0,1);
  240. timSeCsS{c}(s,ft,sp,cs) = timStdDCsS/sqrt(nFiles);
  241. % additionally
  242. switch statParam
  243. case 1
  244. ampGrAvCsS{c}(s,ft,sp,cs) = peak2peak(conSGrAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,cs,ft)); % calculate value from grand averaged response
  245. case 2
  246. ampGrAvCsS{c}(s,ft,sp,cs) = rms(conSGrAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,cs,ft)); % calculate value from grand averaged response
  247. case 3
  248. ampGrAvCsS{c}(s,ft,sp,cs) = trapz(abs(conSGrAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,cs,ft))); % calculate value from grand averaged response
  249. end
  250. [maxGrAvCsV{c}(s,ft,sp,cs),maxGrAvCsI{c}(s,ft,sp,cs)] = max(conSGrAv{c}((winAll{s}(sp,1):winAll{s}(sp,2)),s,cs,ft)); % identify peak and peak index (=timing) per window
  251. timGrAvCsS{c}(s,ft,sp,cs) = maxGrAvCsI{c}(s,ft,sp,cs)/fs*1000; % convert points to timing
  252. end
  253. end
  254. case 2
  255. ampS{c}(:,s,cn,ft,sp) = (data{c}{(s-1)*nCond+cn}(sp,:,ft)); % calculate variable per point
  256. end
  257. end
  258. end
  259. end
  260. end
  261. end
  262. %% run t-test or ANOVA on each time window
  263. effS = zeros(nComb,nStims,nFilt,nSmpl,3,3); % preallocate
  264. switch inclCtrl
  265. case 0
  266. hV = zeros(nComb,nStims,nFilt,nSmpl,3); % preallocate
  267. pV = zeros(nComb,nStims,nFilt,nSmpl,3); % preallocate
  268. ciV = zeros(nComb,nStims,nFilt,nSmpl,3,2); % preallocate
  269. statsV = cell(nComb,nStims,nFilt,nSmpl,3); % preallocate
  270. case {1,2,3}
  271. anovaV = cell(nComb,nStims,nFilt,nSmpl,3); % preallocate
  272. multcompV = cell(nComb,nStims,nFilt,nSmpl,3); % preallocate
  273. within = table([1,2,3]','VariableNames',{'stim_prob'}); % define within model
  274. end
  275. for c = 1:nComb % once for each stimulus combination
  276. for s = 1:nStims % once for each stimulus frequency
  277. for ft = 1:nFilt % once for each filter
  278. for sp = 1:nSmpl % once for each time window
  279. for p = 1:2 % once for each parameter (amplitude, latency, width)
  280. switch p
  281. case 1
  282. varS = ampS;
  283. case 2
  284. varS = timS;
  285. case 3
  286. varS = widS;
  287. end
  288. effS(c,s,ft,sp,p,1) = meanEffectSize(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp),'Effect','cohen').Effect; % calculate effect size; dev vs. std
  289. switch test
  290. case 1
  291. [hV(c,s,ft,sp,p),pV(c,s,ft,sp,p),ciV(c,s,ft,sp,p,:),statsV{c,s,ft,sp,p}] = ttest(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp)); % run t-test
  292. case 2
  293. [pV(c,s,ft,sp,p),hV(c,s,ft,sp,p),statsV{c,s,ft,sp,p}] = ranksum(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp)); % run ranksum test
  294. end
  295. end
  296. switch inclCtrl
  297. case {1,2,3} % if control is included
  298. t = table(varS{c}(:,s,1,ft,sp,p),varS{c}(:,s,2,ft,sp),varS{c}(:,s,3,ft,sp),'VariableNames',{'dev','std','ctrl'}); % required for ANOVA
  299. rm = fitrm(t,'dev-ctrl~1','WithinDesign',within); % required for ANOVA
  300. anovaV{c,s,ft,sp,p} = ranova(rm); % run ANOVA
  301. multcompV{c,s,ft,sp,p} = multcompare(rm,'stim_prob','ComparisonType','bonferroni'); % run multiple comparison to find differences between responses
  302. effS(c,s,ft,sp,p,2) = meanEffectSize(varS{c}(:,s,1,ft,sp),varS{c}(:,s,3,ft,sp),'Effect','cohen').Effect; % calculate effect size; dev vs. ctrl
  303. effS(c,s,ft,sp,p,3) = meanEffectSize(varS{c}(:,s,3,ft,sp),varS{c}(:,s,2,ft,sp),'Effect','cohen').Effect; % ctrl vs. std
  304. end
  305. end
  306. end
  307. end
  308. end
  309. %% save data
  310. fileName = append(fileName,['_',repRate]); % append rep Rate to file name
  311. if omRespI==0
  312. fileName = append(fileName,['_',subStd]); % append Std position to file name
  313. end
  314. switch inclCtrl
  315. case 0
  316. save(fileName,'winAll','winTxt','varS','ampS','timS','widS','ampSNd','hV','pV','ciV','statsV','effS',...
  317. 'ampCsS','ampAvCsS','ampSeCsS','timAvCsS','timSeCsS','ampGrAvCsS','timGrAvCsS','timSNd','widSNd')
  318. case {1,2,3}
  319. save(fileName,'winAll','winTxt','varS','hV','pV','ciV','statsV','anovaV','multcompV','effS')
  320. end
  321. end
  322. end