DD_Cbp.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. % Culster based permutation testing
  2. tic
  3. %% define some variables
  4. clear
  5. inclCtrl = 0; % include control data? (0: no, 1: 50Per, 2: MR, 3: DevOnly)
  6. omRespI = 1; % run stats for omission responses? (0: no, 1: yes)
  7. % define number of std-position datasets
  8. switch omRespI
  9. case 0
  10. nSubStd = 2; % 2 for all datasets
  11. case 1
  12. nSubStd = 1; % except Om dataset (which has only std after dev)
  13. end
  14. % cluster settings
  15. lenMin = 5;
  16. %% load datasets
  17. % load control data and rename important variables
  18. for repRateI = 1:3 % once for each rep rate dataset
  19. for subStdI = 1:nSubStd % once for each std position dataset
  20. switch inclCtrl
  21. 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)
  22. switch repRateI
  23. case 1
  24. repRate = '25ms';
  25. case 2
  26. repRate = '30ms';
  27. case 3
  28. repRate = '50ms';
  29. end
  30. case {1,2} % if 50Per or MR control is included, only use 50 ms dataset
  31. repRate = '50ms';
  32. end
  33. switch subStdI
  34. case 1
  35. subStd = 'SaD';
  36. case 2
  37. subStd = 'SbD';
  38. end
  39. switch omRespI
  40. case 0
  41. switch inclCtrl
  42. case 1
  43. load(['DD_avData_50Per_',repRate,'_',subStd,'.mat'])
  44. load(['DD_avData_50Per_',repRate,'_',subStd,'_perm.mat'])
  45. dataAv_cell_Ctrl = dataAv_cell; % rename
  46. dataAvP_cell_Ctrl = dataAvP_cell; % rename
  47. fileI_Oddb_cell_Ctrl = fileI_Oddb_cell; % rename
  48. fileI_Ctrl_cell_Ctrl = fileI_Ctrl_cell; % rename
  49. case 2
  50. load(['DD_avData_MR_',repRate,'_',subStd,'.mat'])
  51. load(['DD_avData_MR_',repRate,'_',subStd,'_perm.mat'])
  52. dataAv_cell_Ctrl = dataAv_cell; % rename
  53. dataAvP_cell_Ctrl = dataAvP_cell; % rename
  54. fileI_Oddb_cell_Ctrl = fileI_Oddb_cell; % rename
  55. fileI_Ctrl_cell_Ctrl = fileI_Ctrl_cell; % rename
  56. case 3
  57. load(['DD_avData_LowOnly_',repRate,'_',subStd,'.mat'])
  58. load(['DD_avData_LowOnly_',repRate,'_',subStd,'_perm.mat'])
  59. dataAv_cell_LowOnly = dataAv_cell; % rename
  60. dataAvP_cell_LowOnly = dataAvP_cell; % rename
  61. 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
  62. 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
  63. load(['DD_avData_HighOnly_',repRate,'_',subStd,'.mat'])
  64. load(['DD_avData_HighOnly_',repRate,'_',subStd,'_perm.mat'])
  65. dataAv_cell_HighOnly = dataAv_cell; % rename
  66. dataAvP_cell_HighOnly = dataAvP_cell; % rename
  67. end
  68. % load oddball data
  69. load(['DD_avData_Oddball_',repRate,'_',subStd,'.mat'])
  70. load(['DD_avData_Oddball_',repRate,'_',subStd,'_perm.mat'])
  71. case 1
  72. inclCtrl = 0; % no control for OM data
  73. % load OM data
  74. load(['DD_avData_HighOm_',repRate,'.mat'])
  75. load(['DD_avData_HighOm_',repRate,'_perm.mat'])
  76. dataAv_cell_HighOm = dataAv_cell; % rename
  77. dataAvP_cell_HighOm = dataAvP_cell; % rename
  78. load(['DD_avData_LowOm_',repRate,'.mat'])
  79. load(['DD_avData_LowOm_',repRate,'_perm.mat'])
  80. dataAv_cell_LowOm = dataAv_cell; % rename
  81. dataAvP_cell_LowOm = dataAvP_cell; % rename
  82. end
  83. %% do some additional calulations that are required
  84. nSmpl = size(dataAv_cell{1}{1},1); % number of points of each recording
  85. nStims = 2; % number of different stimuli per combination
  86. nFilt = nFilt_cell{1};
  87. switch inclCtrl
  88. case 0
  89. switch omRespI
  90. case 0
  91. fileName = 'DD_CbpData_noCtrl';
  92. case 1
  93. fileName = 'DD_CbpData_Om';
  94. % replace data in dataAv_cell with omission response data
  95. for c = 1:nComb
  96. dataAv_cell{c}{1} = dataAv_cell_HighOm{c}{3};
  97. dataAv_cell{c}{2} = dataAv_cell_HighOm{c}{4};
  98. dataAv_cell{c}{3} = dataAv_cell_LowOm{c}{1};
  99. dataAv_cell{c}{4} = dataAv_cell_LowOm{c}{2};
  100. dataAvP_cell{c}{1} = dataAvP_cell_HighOm{c}{3};
  101. dataAvP_cell{c}{2} = dataAvP_cell_HighOm{c}{4};
  102. dataAvP_cell{c}{3} = dataAvP_cell_LowOm{c}{1};
  103. dataAvP_cell{c}{4} = dataAvP_cell_LowOm{c}{2};
  104. end
  105. end
  106. nCond = 2; % 2 conditions: dev and std
  107. data = dataAv_cell; % only oddball data
  108. dataP = dataAvP_cell; % only oddball data
  109. case {1,2,3}
  110. switch inclCtrl
  111. case 1
  112. fileName = 'DD_statsData_50Per';
  113. case 2
  114. fileName = 'DD_statsData_MR';
  115. case 3
  116. fileName = 'DD_statsData_DevO';
  117. end
  118. nCond = 3; % 3 conditions: dev, std and control
  119. data = cell(size(dataAv_cell));
  120. dataP = cell(size(dataAvP_cell));
  121. for c = 1:nComb % once for each stimulus combination
  122. if inclCtrl==3 % for DevOnly control
  123. dataAv_cell_Ctrl{c}{1} = dataAv_cell_LowOnly{c}{1}; % assign DevOnly Low data as control of stimulus 1
  124. dataAv_cell_Ctrl{c}{2} = dataAv_cell_HighOnly{c}{3}; % assign DevOnly High data as control of stimulus 2
  125. dataAvP_cell_Ctrl{c}{1} = dataAvP_cell_LowOnly{c}{1}; % assign DevOnly Low data as control of stimulus 1
  126. dataAvP_cell_Ctrl{c}{2} = dataAvP_cell_HighOnly{c}{3}; % assign DevOnly High data as control of stimulus 2
  127. end
  128. for s = 1:nStims % once for each stimulus frequency
  129. for cn = 1:nCond % once for each stimulus condition (dev, std, ctrl)
  130. % observed data
  131. switch cn % change dataset depending on condition (Oddball vs. control)
  132. case {1,2} % if oddball
  133. 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)
  134. case 3 % if control
  135. data{c}{(s-1)*nCond+cn} = dataAv_cell_Ctrl{c}{s}(:,fileI_Ctrl_cell_Ctrl{c},:); % concatenate control data of respective stimulus
  136. end
  137. % permutation data
  138. for p = 1:nPerm
  139. switch cn % change dataset depending on condition (Oddball vs. control)
  140. case {1,2} % if oddball
  141. dataP{c}{(s-1)*nCond+cn,p} = dataAvP_cell{c}{(s-1)*2+cn}(:,fileI_Oddb_cell_Ctrl{c},:,p); % concatenate oddball data of respective stimulus & condition (dev/std)
  142. case 3 % if control
  143. dataP{c}{(s-1)*nCond+cn,p} = dataAvP_cell_Ctrl{c}{s}(:,fileI_Ctrl_cell_Ctrl{c},:,p); % concatenate control data of respective stimulus
  144. end
  145. end
  146. end
  147. end
  148. end
  149. end
  150. %% calulate statistical variable (RMS, mean V, etc.) for each sample (points or windows)
  151. varS = cell(1,nComb); % preallocate
  152. varSP = cell(1,nComb); % preallocate
  153. for c = 1:nComb % once for each stimulus combination
  154. nFiles = nFiles_cell{c};
  155. varS{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl); % preallocate
  156. varSP{c} = zeros(nFiles,nStims,nCond,nFilt,nSmpl,nPerm); % preallocate
  157. for s = 1:nStims % once for each stimulus frequency
  158. for cn = 1:nCond % once for each stimulus condition (dev, std, (ctrl))
  159. for ft = 1:nFilt % once for each filter
  160. for sp = 1:nSmpl % once for each sample (windows or points)
  161. % observed data
  162. varS{c}(:,s,cn,ft,sp) = (data{c}{(s-1)*nCond+cn}(sp,:,ft)); % calculate variable per point
  163. % permutation data
  164. for p = 1:nPerm
  165. varSP{c}(:,s,cn,ft,sp,p) = (dataP{c}{(s-1)*nCond+cn}(sp,:,ft,p)); % calculate variable per point
  166. end
  167. end
  168. end
  169. end
  170. end
  171. end
  172. %% run t-test or ANOVA on each time window
  173. cohensD_V = zeros(nComb,nStims,nFilt,nSmpl,3); % preallocate
  174. switch inclCtrl
  175. case 0
  176. hV = zeros(nComb,nStims,nFilt,nSmpl); % preallocate
  177. pV = zeros(nComb,nStims,nFilt,nSmpl); % preallocate
  178. ciV = zeros(nComb,nStims,nFilt,nSmpl,2); % preallocate
  179. statsV = cell(nComb,nStims,nFilt,nSmpl); % preallocate
  180. hVP = zeros(nComb,nStims,nFilt,nSmpl,nPerm); % preallocate
  181. pVP = zeros(nComb,nStims,nFilt,nSmpl,nPerm); % preallocate
  182. ciVP = zeros(nComb,nStims,nFilt,nSmpl,2,nPerm); % preallocate
  183. statsVP = cell(nComb,nStims,nFilt,nSmpl,nPerm); % preallocate
  184. case {1,2,3}
  185. anovaV = cell(nComb,nStims,nFilt,nSmpl); % preallocate
  186. multcompV = cell(nComb,nStims,nFilt,nSmpl); % preallocate
  187. anovaVP = cell(nComb,nStims,nFilt,nSmpl,nPerm); % preallocate
  188. multcompVP = cell(nComb,nStims,nFilt,nSmpl,nPerm); % preallocate
  189. within = table([1,2,3]','VariableNames',{'stim_prob'}); % define within model
  190. end
  191. for c = 1:nComb % once for each stimulus combination
  192. for s = 1:nStims % once for each stimulus frequency
  193. for ft = 1:nFilt % once for each filter
  194. for sp = 1:nSmpl % once for each time window
  195. % observed data
  196. cohensD_V(c,s,ft,sp,1) = CohensD(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp)); % calculate Cohens D; dev vs. std
  197. [hV(c,s,ft,sp),pV(c,s,ft,sp),ciV(c,s,ft,sp,:),statsV{c,s,ft,sp}] = ttest(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp)); % run t-test
  198. % permutation data
  199. for p = 1:nPerm
  200. [hVP(c,s,ft,sp,p),pVP(c,s,ft,sp,p),ciVP(c,s,ft,sp,:,p),statsVP{c,s,ft,sp,p}] = ttest(varSP{c}(:,s,1,ft,sp,p),varSP{c}(:,s,2,ft,sp,p)); % run t-test
  201. end
  202. switch inclCtrl
  203. case {1,2,3} % if control is included
  204. % observed data
  205. t = table(varS{c}(:,s,1,ft,sp),varS{c}(:,s,2,ft,sp),varS{c}(:,s,3,ft,sp),'VariableNames',{'dev','std','ctrl'}); % required for ANOVA
  206. rm = fitrm(t,'dev-ctrl~1','WithinDesign',within); % required for ANOVA
  207. anovaV{c,s,ft,sp} = ranova(rm); % run ANOVA
  208. multcompV{c,s,ft,sp} = multcompare(rm,'stim_prob','ComparisonType','bonferroni'); % run multiple comparison to find differences between responses
  209. cohensD_V(c,s,ft,sp,2) = CohensD(varS{c}(:,s,1,ft,sp),varS{c}(:,s,3,ft,sp)); % calculate Cohens D; dev vs. ctrl
  210. cohensD_V(c,s,ft,sp,3) = CohensD(varS{c}(:,s,3,ft,sp),varS{c}(:,s,2,ft,sp)); % ctrl vs. std
  211. % permutation data
  212. for p = 1:nPerm
  213. anovaVP{c,s,ft,sp,p} = ranova(rm); % run ANOVA
  214. multcompVP{c,s,ft,sp,p} = multcompare(rm,'stim_prob','ComparisonType','bonferroni'); % run multiple comparison to find differences between responses
  215. end
  216. end
  217. end
  218. end
  219. end
  220. end
  221. %% cluster analysis
  222. tStat = zeros(1,nSmpl); % preallocate
  223. vecCl = zeros(nComb,nStims,nFilt,nSmpl);
  224. vecClI = zeros(nComb,nStims,nFilt,nSmpl);
  225. nCl = zeros(nComb,nStims,nFilt);
  226. sCl = cell(nComb,nStims,nFilt);
  227. tStatP = zeros(1,nSmpl,nPerm); % preallocate
  228. vecClP = zeros(nComb,nStims,nFilt,nSmpl);
  229. vecClIP = zeros(nComb,nStims,nFilt,nSmpl);
  230. nClP = zeros(nComb,nStims,nFilt);
  231. sClP = cell(nComb,nStims,nFilt);
  232. sClPmax = zeros(nComb,nStims,nFilt);
  233. clLaI = cell(nComb,nStims,nFilt);
  234. pCl = cell(nComb,nStims,nFilt);
  235. hCl = cell(nComb,nStims,nFilt);
  236. sigCl = zeros(nComb,nStims,nFilt,nSmpl);
  237. vecSigCl = zeros(nComb,nStims,nFilt,nSmpl);
  238. vecSigClI = zeros(nComb,nStims,nFilt,nSmpl);
  239. nSigCl = zeros(nComb,nStims,nFilt);
  240. sSigCl = cell(nComb,nStims,nFilt);
  241. for c = 1:nComb % once for each stimulus combination
  242. for s = 1:nStims % once for each stimulus frequency
  243. for ft = 1:nFilt % once for each filter
  244. for sp = 1:nSmpl % once for each time window
  245. % observed data
  246. tStat(sp) = statsV{c,s,ft,sp}.tstat;
  247. % permutation data
  248. for p = 1:nPerm
  249. tStatP(sp,p) = statsVP{c,s,ft,sp,p}.tstat;
  250. end
  251. end
  252. % observed data
  253. [vecCl(c,s,ft,:),vecClI(c,s,ft,:),nCl(c,s,ft),sCl{c,s,ft}] = findClu(reshape(hV(c,s,ft,:),1,nSmpl),tStat,lenMin); % identify clusters in observed data
  254. % permutation data
  255. for p = 1:nPerm
  256. [vecClP(c,s,ft,:,p),vecClIP(c,s,ft,:),nClP(c,s,ft,p),sClP{c,s,ft,p}] = findClu(reshape(hVP(c,s,ft,:,p),1,nSmpl),tStatP(:,p)',lenMin); % identify clusters in observed data
  257. if isempty(sClP{c,s,ft,p})==1
  258. sClP{c,s,ft,p} = 0; % replace size of non-existent clusters with 0
  259. end
  260. sClPmax(c,s,ft,p) = max(sClP{c,s,ft,p}); % idintify largest cluster for each permutation
  261. end
  262. % compare observed data with value distribution of
  263. % perutation data
  264. for cl = 1:nCl(c,s,ft) % once for each cluster in the observed data
  265. clLaI{c,s,ft}(cl,:) = sClPmax(c,s,ft,:)>sCl{c,s,ft}(cl); % identify how many of the permutation clusters are larger than the observed clusters
  266. pCl{c,s,ft}(cl) = sum(clLaI{c,s,ft}(cl,:),2)/nPerm; % sum up number of permutation clusters that are larger than observed cluster to generate p-value
  267. hCl{c,s,ft}(cl) = pCl{c,s,ft}(cl)<0.3; % identify observed clusters that are larger than 95 % of permutation clusters
  268. end
  269. [vecSigCl(c,s,ft,:),vecSigClI(c,s,ft,:),nSigCl(c,s,ft),sSigCl{c,s,ft}] = findSigClu(reshape(vecCl(c,s,ft,:),1,nSmpl),hCl{c,s,ft}); % identify clusters in observed data
  270. end
  271. end
  272. end
  273. %% save data
  274. fileName = append(fileName,['_',repRate]); % append rep Rate to file name
  275. if omRespI==0
  276. fileName = append(fileName,['_',subStd]); % append Std position to file name
  277. end
  278. switch inclCtrl
  279. case 0
  280. save(fileName,'varS','hV','pV','ciV','statsV','cohensD_V','vecSigCl','vecSigClI','nSigCl','sSigCl','lenMin')
  281. case {1,2,3}
  282. save(fileName,'varS','hV','pV','ciV','statsV','anovaV','multcompV','cohensD_V','vecSigCl','vecSigClI','nSigCl','sSigCl','lenMin')
  283. end
  284. end
  285. end
  286. beep
  287. toc