DD_Processing.m 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. %% define some variables
  2. tic
  3. clear
  4. % remove recordings
  5. remI = 0; % remove certain recordings from analysis? (0: no, 1: yes)
  6. % define recordings to be removed from analysis (if remI==1)
  7. remRec{1} = []; % in dataset 1 (25 ms)
  8. remRec{2} = []; % in dataset 2 (30 ms)
  9. remRec{3} = []; % in dataset 3 (50 ms)
  10. % select processing options
  11. dwnSmpleI = 0; % down sample data? (1: yes, 0: no)
  12. dwnSmplRate = 5000; % which should be the new sampling rate if signal is down sampled?
  13. detrendI = 0; % detrend data? (1: yes, 0: no)
  14. zsNormI = 0; % z-normalise data data? (1: yes, 0: no)
  15. demeanI = 0; % demean data? (this is independent from baseline correction!)
  16. shCtrlI = 0; % shuffle control trials before averaging?
  17. subsampleI = 1; % calculate averages from all responses (= 0) or only from dev after std and std before dev (= 1)?
  18. % subStd = 2; % decide which std responses are used when subsampling; 1: Std after Dev, 2: Std before Dev (does not affect omission responses)
  19. recDurMult = 1; % multiplier of recdur (1 = original rec dur)
  20. % define channels to be processed; type "all" to process all channels
  21. channels = ["Plus"];
  22. % filter settings
  23. type = 1; % 1: Butterworth, 2: IFFT
  24. order = 4;
  25. lowc = [10,45,50,55]; % low cut frequency in Hz
  26. hic = 1500; % high cut frequency in Hz
  27. nFilt = size(lowc,2)+1; % number of filters used (+1 because of unfiltered data)
  28. % rejection criterion
  29. artRejI = 1; % turn artifact rejection on (1) or off (0)
  30. rejThr = 200; % uV threshold (every trial with min/max value exceeding this will be rejected before averaging)
  31. remTrArtI = 1; % should trigger artifact be removed from the data?
  32. trArtDate = '20231220'; % day before which trigger artifact existed
  33. % baseline correction settings
  34. blcWin = 0.001; % length of time window for baseline correction in s
  35. chirpPeak = [0.00648,0.00842]; % amplitude peaks of chirps (first: low, second: high)
  36. blcEnd = chirpPeak; % end of baseline correction window in s (first: low freq chirp, second: high freq chirp)
  37. % speaker distance
  38. spDis = 0.26; % distance from ear to speaker in m (to correct for sound-travel delay)
  39. % extract consecutive standards
  40. nConS = 8; % number of consecutive standards to be extracted from oddball sequences
  41. exactNConSI = 1; % should only the exact number (and not less) of consecutive standards be used? (= 1)
  42. % permutation
  43. nPerm = 1; % number of permutations (dev and std)
  44. %% data processing
  45. for subStd = 2:2 % once for Std before Dev, once for Std after Dev
  46. for repDaSe = 1:3 % once for each repetition rate
  47. switch repDaSe
  48. case 1 % 25 ms
  49. repRateName = '_25ms';
  50. nRunType = [1,3,4,5,6]; % Oddball, Low only, High only, Low OM, High OM (50Per missing)
  51. case 2 % 30 ms
  52. repRateName = '_30ms';
  53. nRunType = [1,3,4,5,6]; % Oddball, Low only, High only, Low OM, High OM (50Per missing)
  54. case 3 % 50 ms
  55. repRateName = '_50ms';
  56. nRunType = (1:6); % Oddball, 50Per, Low only, High only, Low OM, High OM
  57. end
  58. % name combinations and load data
  59. nRunType = 1; % ONLY FOR TESTING REASONS - REMOVE!!!
  60. for runType = nRunType % run once for each condition
  61. combName = ["Low,High"];
  62. switch runType
  63. case 1
  64. load(['DD_Data_Oddball',repRateName,'.mat'])
  65. fileName = append("DD_avData_Oddball",repRateName);
  66. case 2
  67. load(['DD_Data_50Per',repRateName,'.mat'])
  68. fileName = append("DD_avData_50Per",repRateName);
  69. case {3,4,5,6}
  70. load(['DD_Data_OR',repRateName,'.mat'])
  71. switch runType
  72. case 3
  73. fileName = append("DD_avData_LowOnly",repRateName);
  74. case 4
  75. fileName = append("DD_avData_HighOnly",repRateName);
  76. case 5
  77. fileName = append("DD_avData_HighOm",repRateName);
  78. case 6
  79. fileName = append("DD_avData_LowOm",repRateName);
  80. end
  81. end
  82. nComb = size(combName,1); % number of different stimulus combination to be processed
  83. dataAv_cell = cell(1,nComb); % preallocate
  84. dataGrAv_cell = cell(1,nComb); % preallocate
  85. dataDifAv_cell = cell(1,nComb); % preallocate
  86. dataDifGrAv_cell = cell(1,nComb); % preallocate
  87. dataSe_cell = cell(1,nComb); % preallocate
  88. dataAvP_cell = cell(1,nComb); % preallocate
  89. dataGrAvP_cell = cell(1,nComb); % preallocate
  90. dataDifAvP_cell = cell(1,nComb); % preallocate
  91. dataDifGrAvP_cell = cell(1,nComb); % preallocate
  92. dataSeP_cell = cell(1,nComb); % preallocate
  93. filenames_stim_cell = cell(1,nComb); % preallocate
  94. recID_cell = cell(1,nComb); % preallocate
  95. fileI_Oddb_cell = cell(1,nComb); % preallocate
  96. fileI_Ctrl_cell = cell(1,nComb); % preallocate
  97. timetr_cell = cell(1,nComb); % preallocate
  98. pts2begin_cell = cell(1,nComb); % preallocate
  99. nCh_s_cell = cell(1,nComb); % preallocate
  100. nBlcks_cell = cell(1,nComb); % preallocate
  101. nFiles_cell = cell(1,nComb); % preallocate
  102. nFilt_cell = cell(1,nComb); % preallocate
  103. nDevUsed_cell = cell(1,nComb); % preallocate
  104. nStdUsed_cell = cell(1,nComb); % preallocate
  105. stimDur_cell = cell(1,nComb); % preallocate
  106. stimDelay_cell = cell(1,nComb); % preallocate
  107. fs_cell = cell(1,nComb); % preallocate
  108. ch_idx_cell = cell(1,nComb); % preallocate
  109. nameCh_cell = cell(1,nComb); % preallocate
  110. chLbl_cell = cell(1,nComb); % preallocate
  111. devR_cell = cell(1,nComb); % preallocate
  112. stdR_cell = cell(1,nComb); % preallocate
  113. conSAv = cell(1,nComb); % preallocate
  114. conSGrAv = cell(1,nComb); % preallocate
  115. conSSe = cell(1,nComb); % preallocate
  116. conST = cell(1,nComb); % preallocate
  117. for c = 1:nComb % run analysis once for each stimulation-combination
  118. switch runType
  119. case 1 % Oddball
  120. data = Data_Oddball_Low_High;
  121. case 2 % 50Per
  122. data = Data_50Per_Low_High;
  123. case 3 % Low only
  124. data = Data_OR_Low_HighOm;
  125. case 4 % High only
  126. data = Data_OR_LowOm_High;
  127. case 5 % High OM (Low present)
  128. data = Data_OR_Low_HighOm;
  129. case 6 % Low OM (High present)
  130. data = Data_OR_LowOm_High;
  131. end
  132. % Organise dataset in multiple variables (in separate script)
  133. DD_OrgData
  134. % extract data of channel to be processed
  135. ch_idx = zeros(nCh_s(1),nFiles,'single'); % preallocate
  136. rec_raw_ch = cell(nFiles,1); % preallocate
  137. recRawCut = zeros(blockLen,nBlcks,nFiles); % preallocate
  138. for f = 1:nFiles
  139. ch_idx(:,f) = find(ismember(chLbl(f,:),nameCh)); % calculate indices of channels to be processed
  140. rec_raw_ch{f} = rec_raw{f}(ch_idx(:,f),:); % pick data from channels to be processed
  141. recRawCut(:,:,f) = cutblockTrial(rec_raw_ch{f},trigs_all(f,:,:),blockLen,nBlcks); % cut out buffers and overlengths from raw data and split data into step-blocks
  142. % figure; plot(recRawCut(:,:,f)) % plot raw trace to identify artifacts
  143. end
  144. % artifact rejection
  145. recRawCut = reshape(recRawCut,pSmpl,nTrials,nBlcks,nFiles); % reshape to have one trial in each column
  146. nTrialsAcc = zeros(nBlcks,nFiles); % preallocate
  147. seqAcc = zeros(nTrials,nBlcks,nFiles); % preallocate
  148. switch artRejI
  149. case 0 % if artifact rejection is turned off
  150. nTrialsAcc(:) = nTrials;
  151. for f = 1:nFiles
  152. for b = 1:nBlcks
  153. seqAcc(:,b,f) = seq(f,:);
  154. end
  155. end
  156. case 1 % run if artifact rejection is turned on
  157. % preallocate
  158. maxV = zeros(1,nTrials,nBlcks,nFiles);
  159. rejIdx = zeros(1,nTrials,nBlcks,nFiles);
  160. for f = 1:nFiles
  161. for b = 1:nBlcks
  162. for t = 1:nTrials
  163. maxV(1,t,b,f) = max(abs(recRawCut(:,t,b,f))); % find (absolute) max value in each trial
  164. rejIdx(1,t,b,f) = maxV(:,t,b,f)<rejThr; % compare max value of trial with rejection threshold, "1" if max is smaller than threshold -> trial will be accepted later
  165. end % repeat for every trial in current file and (level-)step
  166. nTrialsAcc(b,f) = sum(rejIdx(:,:,b,f)); % count number of accepted trials for current file and step
  167. recRawCut(:,1:nTrialsAcc(b,f),b,f) = recRawCut(:,logical(rejIdx(:,:,b,f)),b,f); % apply previously created rejection index-array as logical array on 2nd dimension (trials) of filtered data. Indexing is applied on all filters (5th dim) simultaneously; array is filled only until number of accepted responses is reached (3rd dim), the rest is still filled with zeros
  168. seqAcc(1:nTrialsAcc(b,f),b,f) = seq(f,logical(rejIdx(:,:,b,f)));
  169. end
  170. end
  171. end
  172. % remove trigger artifact
  173. if remTrArtI==1
  174. for f = 1:nFiles
  175. switch artDateI(f)
  176. case 0 % if no Stimtrak artifact exists
  177. nArt = 1; % remove only artifact at the beginning
  178. case 1 % if Stimtrak artifact exists
  179. nArt = 2; % remove both artifacts, at the beginning and 11 ms later
  180. end
  181. for art = 1:nArt % once for each artifact per stimulus
  182. switch art
  183. case 1
  184. artDur = 0.0015; % duration of trigger artifact in ms
  185. artStartPts = 1; % for first artifact, startimg point is always 1
  186. case 2
  187. artStart = 0.0107; % start of trigger artifact in ms
  188. artDur = 0.0015; % duration of trigger artifact in ms
  189. artStartPts = round(artStart*fs); % convert start of trigger artifact to points
  190. end
  191. artDurPts = round(artDur*fs); % convert duration of trigger artifact to points
  192. artEndPts = artStartPts+artDurPts; % calculate end of trigger artifact in points
  193. for b = 1:nBlcks
  194. for t = 1:nTrials
  195. recRawCut(artStartPts:artEndPts,t,b,f) = linspace(recRawCut(artStartPts,t,b,f),recRawCut(artEndPts,t,b,f),artDurPts+1); % replace artifact by linear vector from start to end
  196. end
  197. end
  198. end
  199. end
  200. end
  201. % process data
  202. recPro = recRawCut; % rename
  203. recFilt = zeros(pSmpl*nTrials,nBlcks,nFiles,nFilt-1); % preallocate
  204. for f = 1:nFiles
  205. for b = 1:nBlcks
  206. % detrending
  207. if detrendI==1
  208. recPro(:,1:nTrialsAcc(b,f),b,f) = detrend(recPro(:,1:nTrialsAcc(b,f),b,f));
  209. end
  210. % z score normalisation
  211. if zsNormI==1
  212. recPro(:,1:nTrialsAcc(b,f),b,f) = zscoreJo(recPro(:,1:nTrialsAcc(b,f),b,f),pSmpl);
  213. end
  214. % demeaning
  215. if demeanI==1
  216. recPro(:,1:nTrialsAcc(b,f),b,f) = demean(recPro(:,1:nTrialsAcc(b,f),b,f));
  217. end
  218. % filtering
  219. recProRS = reshape(recPro,nTrials*pSmpl,nBlcks,nFiles);
  220. for ft = 1:nFilt-1 % "-1" because "nFilt" includes raw-array which must be excluded here
  221. recFilt(1:nTrialsAcc(b,f)*pSmpl,b,f,ft) = Filter_Butter(recProRS(1:nTrialsAcc(b,f)*pSmpl,b,f),order,lowc(ft),hic,"bandpass",fs);
  222. end
  223. end
  224. end
  225. recProFilt = cat(4,recProRS,recFilt); % concatenate unfiltered and filtered data in 4th dimension
  226. recProFilt = reshape(recProFilt,pSmpl,nTrials,nBlcks,nFiles,nFilt); % reshape to split raw-data into separate trials (2nd dimension)
  227. % split blocks into deviant and standard responses
  228. [devR,stdR,nDevAcc,nStdAcc] = sortBlck(recProFilt,seqAcc,nTrialsAcc);
  229. nDevUsed = nDevAcc; % define number of accepted deviants as number of used deviants --> changes later again if subsampling is on!
  230. nStdUsed = nStdAcc; % define number of accepted standards as number of used standards --> changes later again if subsampling is on!
  231. % extract sequences of consecutive standards
  232. avNStd = countConS(recProFilt,seqAcc,nTrialsAcc); % extract clusters of consecutive standards
  233. [conS,conSI] = findConS(recProFilt,seqAcc,nTrialsAcc,nConS,exactNConSI); % extract clusters of consecutive standards
  234. conST{c} = zeros(nBlcks,nFiles);
  235. for f = 1:nFiles
  236. for b = 1:nBlcks
  237. conST{c}(b,f) = size(conSI{b,f},2);
  238. end
  239. end
  240. % perform baseline correction: after Dev/Std split because it
  241. % depends on processed stimulus (different to bat analysis)
  242. blcStartPts = round(pts2begin+(blcEnd-blcWin)*fs); % transform time window for baseline correction into points
  243. blcEndPts = round(pts2begin+blcEnd*fs);
  244. conSRs = cell(nBlcks,nFiles); % preallocate
  245. for f = 1:nFiles
  246. for b = 1:nBlcks
  247. switch runType % blc changes for omission responses
  248. case {1,2,3,4}
  249. switch b % change time window for baseline correction depending on processed block (ADev/BStd & BDev/AStd) and stim combination (c)
  250. case 1
  251. blcStartPtsDev = blcStartPts(1);
  252. blcStartPtsStd = blcStartPts(2);
  253. blcEndPtsDev = blcEndPts(1);
  254. blcEndPtsStd = blcEndPts(2);
  255. case 2
  256. blcStartPtsDev = blcStartPts(2);
  257. blcStartPtsStd = blcStartPts(1);
  258. blcEndPtsDev = blcEndPts(2);
  259. blcEndPtsStd = blcEndPts(1);
  260. end
  261. case 5 % High OM: Although high was omitted, we care about a potential "Low" omission response, triggered by the presented low freq chirps. Hence bcl only for low-timing
  262. blcStartPtsDev = blcStartPts(1);
  263. blcStartPtsStd = blcStartPts(1);
  264. blcEndPtsDev = blcEndPts(1);
  265. blcEndPtsStd = blcEndPts(1);
  266. case 6 % Low OM: Although low was omitted, we care about a potential "High" omission response, triggered by the presented high freq chirps. Hence bcl only for high-timing
  267. blcStartPtsDev = blcStartPts(2);
  268. blcStartPtsStd = blcStartPts(2);
  269. blcEndPtsDev = blcEndPts(2);
  270. blcEndPtsStd = blcEndPts(2);
  271. end
  272. for ft = 1:nFilt
  273. devR(:,1:nDevAcc(b,f),b,f,ft) = blCorr(devR(:,1:nDevAcc(b,f),b,f,ft),blcStartPtsDev,blcEndPtsDev);
  274. stdR(:,1:nStdAcc(b,f),b,f,ft) = blCorr(stdR(:,1:nStdAcc(b,f),b,f,ft),blcStartPtsStd,blcEndPtsStd);
  275. % TEST normalise each cluster instead of each
  276. % response in cluster
  277. conSRs{b,f} = zeros(pSmpl*nConS,size(conS{b,f},3),nFilt); % preallocate
  278. for cs = 1:nConS
  279. conSRs{b,f}(1+pSmpl*(cs-1):pSmpl*cs,:,ft) = conS{b,f}(:,cs,:,ft); % concatenate consecutive responses of one cluster (required for blc)
  280. end
  281. conSRs{b,f}(:,:,ft) = blCorr(reshape(conSRs{b,f}(:,:,ft),pSmpl*nConS,[]),blcStartPtsStd,blcEndPtsStd); % perform blc
  282. for cs = 1:nConS
  283. conS{b,f}(:,cs,:,ft) = conSRs{b,f}(1+pSmpl*(cs-1):pSmpl*cs,:,ft); % split responses again
  284. end
  285. % ALTERNATIVE - normalise each response in
  286. % cluster
  287. % for cs = 1:nConS
  288. % conS{b,f}(:,cs,:,ft) = blCorr(reshape(conS{b,f}(:,cs,:,ft),pSmpl,[]),blcStartPtsStd,blcEndPtsStd);
  289. % end
  290. end
  291. end
  292. end
  293. % subsample oddball responses (extract dev after std & std before
  294. % dev) and reassign variables "nDevUsed" & "nStdUsed"
  295. % ATTENTION: this section only works correctly if the same files
  296. % are available for Oddball and Control conditions!
  297. switch subsampleI
  298. case 1
  299. switch runType
  300. case {1,2,3,4} % Dev after Std, Std before Dev
  301. switch subStd
  302. case 1 % std after dev
  303. [devR,stdR,nTrialsDev,nTrialsStd] = subsampleOm(devR,stdR,seqAcc,nTrialsAcc); % subsample oddball responses --> number of trials will be much less afterwards (= nTrialsSub)
  304. nDevUsed = nTrialsDev; % define number of subsampled deviants as number of used deviants
  305. nStdUsed = nTrialsStd; % define number of subsampled standards as number of used standards
  306. case 2 % std before dev
  307. [devR,stdR,nTrialsSub] = subsample(devR,stdR,seqAcc,nTrialsAcc); % subsample oddball responses --> number of trials will be much less afterwards (= nTrialsSub)
  308. nDevUsed = nTrialsSub; % define number of subsampled deviants as number of used deviants
  309. nStdUsed = nTrialsSub; % define number of subsampled standards as number of used standards
  310. end
  311. switch runType
  312. case 1
  313. nDevUsed_oddb{c} = nDevUsed; % assign number of used deviants to separate variable. (std not necessary bc ctrls will only need number of deviants. Additionally, nStdAcc and nDevAcc should be equal anyway if subsampling is on)
  314. end
  315. case {5,6} % Dev after Std, Std after Dev
  316. [devR,stdR,nTrialsDev,nTrialsStd] = subsampleOm(devR,stdR,seqAcc,nTrialsAcc); % subsample oddball responses --> number of trials will be much less afterwards (= nTrialsSub)
  317. nDevUsed = nTrialsDev; % define number of subsampled deviants as number of used deviants
  318. nStdUsed = nTrialsStd; % define number of subsampled standards as number of used standards
  319. end
  320. end
  321. % if activated, run random perutation to shuffle 50Per and MR responses --> important for 50Per
  322. % control: to make sure not only the earliest responses are used
  323. % for averaging
  324. if shCtrlI==1
  325. switch runType
  326. case 2
  327. for f = 1:nFiles
  328. for b = 1:nBlcks
  329. rDev = randperm(nDevUsed(b,f)); % create random vector containing all used dev responses (they cover the whole sequence)
  330. devR(:,1:nDevUsed(b,f),b,f,:) = devR(:,rDev,b,f,:); % shuffle those vectors that contain an actual response and no zeros --> timing within sequence is now irrelevant
  331. rStd = randperm(nStdUsed(b,f)); % repeat the same for std responses
  332. stdR(:,1:nStdUsed(b,f),b,f,:) = stdR(:,rStd,b,f,:);
  333. end
  334. end
  335. end
  336. end
  337. % calculate average & grand-average of sorted responses
  338. switch runType
  339. case 2 % 50 Per
  340. nDevUsed = nDevUsed_oddb{c}; % change nDevUsed to trial number from oddball recording to end up with the same number of trials for averaging
  341. nStdUsed = nDevUsed_oddb{c}; % do the same for nStdUsed
  342. end
  343. devAv = zeros(pSmpl,nBlcks,nFiles,nFilt);
  344. stdAv = zeros(pSmpl,nBlcks,nFiles,nFilt);
  345. conSAv{c} = zeros(pSmpl,nBlcks,nFiles,nConS,nFilt);
  346. for f = 1:nFiles
  347. for b = 1:nBlcks
  348. devAv(:,b,f,:) = mean(devR(:,1:nDevUsed(b,f),b,f,:),2); % averaging is performed only on those vectors that contain an actual response and not only zeros (2nd dim)
  349. stdAv(:,b,f,:) = mean(stdR(:,1:nStdUsed(b,f),b,f,:),2);
  350. for cs = 1:nConS
  351. conSAv{c}(:,b,f,cs,:) = mean(conS{b,f}(:,cs,conSI{b,f}(cs,:),:),3);
  352. end
  353. end
  354. end
  355. % perform permutations
  356. devAvP = zeros(pSmpl,nBlcks,nFiles,nFilt,nPerm);
  357. stdAvP = zeros(pSmpl,nBlcks,nFiles,nFilt,nPerm);
  358. for f = 1:nFiles
  359. for b = 1:nBlcks
  360. devRU = devR(:,1:nDevUsed(b,f),b,f,:); % exctract meaningful data
  361. stdRU = stdR(:,1:nStdUsed(b,f),b,f,:);
  362. trialsRU = cat(2,devRU,stdRU); % concatenate dev and std data
  363. for p = 1:nPerm
  364. trialsRP = trialsRU(:,(randperm(size(trialsRU,2))),:,:,:); % shuffle dev and std trials
  365. devRP = trialsRP(:,(1:nDevUsed(b,f)),:,:,:); % use first half of shuffled data as dev permutation
  366. stdRP = trialsRP(:,(nDevUsed(b,f)+1:end),:,:,:); % use second half of shuffled data as std permutation
  367. devAvP(:,b,f,:,p) = mean(devRP,2); % calculate average
  368. stdAvP(:,b,f,:,p) = mean(stdRP,2);
  369. end
  370. end
  371. end
  372. % calculate grand average
  373. devGrAv = reshape(mean(devAv,3),pSmpl,nBlcks,nFilt);
  374. stdGrAv = reshape(mean(stdAv,3),pSmpl,nBlcks,nFilt);
  375. conSGrAv{c} = reshape(mean(conSAv{c},3),pSmpl,nBlcks,nConS,nFilt);
  376. devGrAvP = reshape(mean(devAvP,3),pSmpl,nBlcks,nFilt,nPerm);
  377. stdGrAvP = reshape(mean(stdAvP,3),pSmpl,nBlcks,nFilt,nPerm);
  378. % calculate standard deviation
  379. devStdD = reshape(std(devAv,0,3),pSmpl,nBlcks,nFilt);
  380. stdStdD = reshape(std(stdAv,0,3),pSmpl,nBlcks,nFilt);
  381. conSStdD = reshape(std(conSAv{c},0,3),pSmpl,nBlcks,nConS,nFilt);
  382. devStdDP = reshape(std(devAvP,0,3),pSmpl,nBlcks,nFilt,nPerm);
  383. stdStdDP = reshape(std(stdAvP,0,3),pSmpl,nBlcks,nFilt,nPerm);
  384. % calculate standard error
  385. devSe = devStdD/sqrt(nFiles);
  386. stdSe = stdStdD/sqrt(nFiles);
  387. conSSe{c} = conSStdD/sqrt(nFiles);
  388. devSeP = devStdDP/sqrt(nFiles);
  389. stdSeP = stdStdDP/sqrt(nFiles);
  390. % split dataset into several sub-variables for simplisity
  391. switch runType
  392. case {1,3,4,5,6}
  393. ADev{c} = devAv(:,1,:,:); % A is deviant in block 1 (AB)
  394. ADev{c} = reshape(ADev{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  395. AStd{c} = stdAv(:,2,:,:); % A is standard in block 2 (BA)
  396. AStd{c} = reshape(AStd{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  397. BDev{c} = devAv(:,2,:,:); % B is deviant in block 2 (BA)
  398. BDev{c} = reshape(BDev{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  399. BStd{c} = stdAv(:,1,:,:); % B is standard in block 1 (AB)
  400. BStd{c} = reshape(BStd{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  401. ADevGrAv{c} = devGrAv(:,1,:);
  402. ADevGrAv{c} = reshape(ADevGrAv{c},pSmpl,nFilt); % reshape grav into 2D array
  403. AStdGrAv{c} = stdGrAv(:,2,:);
  404. AStdGrAv{c} = reshape(AStdGrAv{c},pSmpl,nFilt); % reshape grav data into 2D array
  405. BDevGrAv{c} = devGrAv(:,2,:);
  406. BDevGrAv{c} = reshape(BDevGrAv{c},pSmpl,nFilt); % reshape grav data into 2D array
  407. BStdGrAv{c} = stdGrAv(:,1,:);
  408. BStdGrAv{c} = reshape(BStdGrAv{c},pSmpl,nFilt); % reshape grav data into 2D array
  409. ADevSe{c} = devSe(:,1,:);
  410. ADevSe{c} = reshape(ADevSe{c},pSmpl,nFilt); % reshape standard error 2D array
  411. AStdSe{c} = stdSe(:,2,:);
  412. AStdSe{c} = reshape(AStdSe{c},pSmpl,nFilt); % reshape standard error into 2D array
  413. BDevSe{c} = devSe(:,2,:);
  414. BDevSe{c} = reshape(BDevSe{c},pSmpl,nFilt); % reshape standard error into 2D array
  415. BStdSe{c} = stdSe(:,1,:);
  416. BStdSe{c} = reshape(BStdSe{c},pSmpl,nFilt); % reshape standard error into 2D array
  417. % do the same for permutation data
  418. ADevP{c} = devAvP(:,1,:,:,:); % A is deviant in block 1 (AB)
  419. ADevP{c} = reshape(ADevP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  420. AStdP{c} = stdAvP(:,2,:,:,:); % A is standard in block 2 (BA)
  421. AStdP{c} = reshape(AStdP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  422. BDevP{c} = devAvP(:,2,:,:,:); % B is deviant in block 2 (BA)
  423. BDevP{c} = reshape(BDevP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  424. BStdP{c} = stdAvP(:,1,:,:,:); % B is standard in block 1 (AB)
  425. BStdP{c} = reshape(BStdP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  426. ADevGrAvP{c} = devGrAvP(:,1,:,:);
  427. ADevGrAvP{c} = reshape(ADevGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav into 3D array
  428. AStdGrAvP{c} = stdGrAvP(:,2,:,:);
  429. AStdGrAvP{c} = reshape(AStdGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav data into 3D array
  430. BDevGrAvP{c} = devGrAvP(:,2,:,:);
  431. BDevGrAvP{c} = reshape(BDevGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav data into 3D array
  432. BStdGrAvP{c} = stdGrAvP(:,1,:,:);
  433. BStdGrAvP{c} = reshape(BStdGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav data into 3D array
  434. ADevSeP{c} = devSeP(:,1,:,:);
  435. ADevSeP{c} = reshape(ADevSeP{c},pSmpl,nFilt,nPerm); % reshape standard error 3D array
  436. AStdSeP{c} = stdSeP(:,2,:,:);
  437. AStdSeP{c} = reshape(AStdSeP{c},pSmpl,nFilt,nPerm); % reshape standard error into 3D array
  438. BDevSeP{c} = devSeP(:,2,:,:);
  439. BDevSeP{c} = reshape(BDevSeP{c},pSmpl,nFilt,nPerm); % reshape standard error into 3D array
  440. BStdSeP{c} = stdSeP(:,1,:,:);
  441. BStdSeP{c} = reshape(BStdSeP{c},pSmpl,nFilt,nPerm); % reshape standard error into 3D array
  442. case 2
  443. % sorted responses
  444. ACtrl{c} = devAv(:,1,:,:); % A is deviant in block 1 (AB) --> in this case (50Per), it does not matter which condition is used, as long as it is the right stimulus
  445. ACtrl{c} = reshape(ACtrl{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  446. BCtrl{c} = devAv(:,2,:,:); % B is deviant in block 2 (BA) --> in this case (50Per), it does not matter which condition is used, as long as it is the right stimulus
  447. BCtrl{c} = reshape(BCtrl{c},pSmpl,nFiles,nFilt); % reshape av data into 3D array
  448. ACtrlGrAv{c} = devGrAv(:,1,:);
  449. ACtrlGrAv{c} = reshape(ACtrlGrAv{c},pSmpl,nFilt); % reshape grav into 2D array
  450. BCtrlGrAv{c} = devGrAv(:,2,:);
  451. BCtrlGrAv{c} = reshape(BCtrlGrAv{c},pSmpl,nFilt); % reshape grav data into 2D array
  452. ACtrlSe{c} = devSe(:,1,:);
  453. ACtrlSe{c} = reshape(ACtrlSe{c},pSmpl,nFilt); % reshape standard error into 2D array
  454. BCtrlSe{c} = devSe(:,2,:);
  455. BCtrlSe{c} = reshape(BCtrlSe{c},pSmpl,nFilt); % reshape standard error into 2D array
  456. % do the same for permutation data
  457. ACtrlP{c} = devAvP(:,1,:,:,:); % A is deviant in block 1 (AB) --> in this case (50Per), it does not matter which condition is used, as long as it is the right stimulus
  458. ACtrlP{c} = reshape(ACtrlP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  459. BCtrlP{c} = devAvP(:,2,:,:,:); % B is deviant in block 2 (BA) --> in this case (50Per), it does not matter which condition is used, as long as it is the right stimulus
  460. BCtrlP{c} = reshape(BCtrlP{c},pSmpl,nFiles,nFilt,nPerm); % reshape av data into 4D array
  461. ACtrlGrAvP{c} = devGrAvP(:,1,:,:);
  462. ACtrlGrAvP{c} = reshape(ACtrlGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav into 3D array
  463. BCtrlGrAvP{c} = devGrAvP(:,2,:,:);
  464. BCtrlGrAvP{c} = reshape(BCtrlGrAvP{c},pSmpl,nFilt,nPerm); % reshape grav data into 3D array
  465. ACtrlSeP{c} = devSeP(:,1,:,:);
  466. ACtrlSeP{c} = reshape(ACtrlSeP{c},pSmpl,nFilt,nPerm); % reshape standard error into 3D array
  467. BCtrlSeP{c} = devSeP(:,2,:,:);
  468. BCtrlSeP{c} = reshape(BCtrlSeP{c},pSmpl,nFilt,nPerm); % reshape standard error into 3D array
  469. end
  470. % organise processed dev and std responses in cell array
  471. switch runType
  472. case {1,3,4,5,6}
  473. dataAv= {ADev{c},AStd{c},BDev{c},BStd{c}};
  474. dataGrAv = {ADevGrAv{c},AStdGrAv{c},BDevGrAv{c},BStdGrAv{c}};
  475. dataDifAv = [];
  476. dataDifGrAv = [];
  477. dataSe = {ADevSe{c},AStdSe{c},BDevSe{c},BStdSe{c}};
  478. % permutation data
  479. dataAvP= {ADevP{c},AStdP{c},BDevP{c},BStdP{c}};
  480. dataGrAvP = {ADevGrAvP{c},AStdGrAvP{c},BDevGrAvP{c},BStdGrAvP{c}};
  481. dataDifAvP = [];
  482. dataDifGrAvP = [];
  483. dataSeP = {ADevSeP{c},AStdSeP{c},BDevSeP{c},BStdSeP{c}};
  484. case 2
  485. dataAv = {ACtrl{c},BCtrl{c}};
  486. dataGrAv = {ACtrlGrAv{c},BCtrlGrAv{c}};
  487. dataDifAv = [];
  488. dataDifGrAv = []; % empty bc unused (use line below if needed)
  489. % dataDifAv = {ADifDev{c},ADifStd{c},BDifDev{c},BDifStd{c}};
  490. % dataDifGrAv = {ADifDevGrAv{c},ADifStdGrAv{c},BDifDevGrAv{c},BDifStdGrAv{c}};
  491. dataSe = {ACtrlSe{c},BCtrlSe{c}};
  492. % permutation data
  493. dataAvP = {ACtrlP{c},BCtrlP{c}};
  494. dataGrAvP = {ACtrlGrAvP{c},BCtrlGrAvP{c}};
  495. dataDifAvP = [];
  496. dataDifGrAvP = []; % empty bc unused (use line below if needed)
  497. dataSeP = {ACtrlSeP{c},BCtrlSeP{c}};
  498. end
  499. % for consecutive std clusters: swap blocks to have A in
  500. % block 1 and B in block 2 - to be consistent with the
  501. % rest
  502. conST{c}([1,2],:) = conST{c}([2,1],:); % swap blocks
  503. conSAv{c}(:,[1,2],:,:,:) = conSAv{c}(:,[2,1],:,:,:); % swap blocks
  504. conSGrAv{c}(:,[1,2],:,:) = conSGrAv{c}(:,[2,1],:,:); % swap blocks
  505. conSSe{c}(:,[1,2],:,:) = conSSe{c}(:,[2,1],:,:); % swap blocks
  506. % concatenate important data in another cell array with one cell
  507. % for each stimulation-condition
  508. dataAv_cell{c} = dataAv;
  509. dataGrAv_cell{c} = dataGrAv;
  510. dataDifAv_cell{c} = dataDifAv;
  511. dataDifGrAv_cell{c} = dataDifGrAv;
  512. dataSe_cell{c} = dataSe;
  513. dataAvP_cell{c} = dataAvP;
  514. dataGrAvP_cell{c} = dataGrAvP;
  515. dataDifAvP_cell{c} = dataDifAvP;
  516. dataDifGrAvP_cell{c} = dataDifGrAvP;
  517. dataSeP_cell{c} = dataSeP;
  518. filenames_stim_cell{c} = filenames_stim;
  519. recID_cell{c} = recID;
  520. fileI_Oddb_cell{c} = fileI_Oddb;
  521. fileI_Ctrl_cell{c} = fileI_Ctrl;
  522. timetr_cell{c} = timetr;
  523. pts2begin_cell{c} = pts2begin;
  524. nCh_s_cell{c} = nCh_s;
  525. nBlcks_cell{c} = nBlcks;
  526. nFiles_cell{c} = nFiles;
  527. nFilt_cell{c} = nFilt;
  528. stimDur_cell{c} = stimDur;
  529. stimDelay_cell{c} = stimDelay;
  530. fs_cell{c} = fs;
  531. ch_idx_cell{c} = ch_idx;
  532. nameCh_cell{c} = nameCh;
  533. chLbl_cell{c} = chLbl;
  534. nDevUsed_cell{c} = nDevUsed;
  535. nStdUsed_cell{c} = nStdUsed;
  536. devR_cell{c} = devR;
  537. stdR_cell{c} = stdR;
  538. end
  539. switch runType
  540. case {1,2,3,4}
  541. switch subStd
  542. case 1 % std after dev
  543. fileName = append(fileName,"_SaD");
  544. case 2
  545. fileName = append(fileName,"_SbD");
  546. end
  547. end
  548. save(fileName,'dataAv_cell','dataGrAv_cell','dataDifAv_cell','dataDifGrAv_cell','dataSe_cell',...
  549. 'filenames_stim_cell','recID_cell',...
  550. 'fileI_Oddb_cell','fileI_Ctrl_cell','timetr_cell','pts2begin_cell','combName',...
  551. 'nComb','nCh_s_cell','nBlcks_cell','nFiles_cell','nFilt_cell','nDevUsed_cell','nStdUsed_cell',...
  552. 'stimDur_cell','stimDelay_cell','fs_cell','ch_idx_cell','nameCh_cell',...
  553. 'chLbl_cell','subsampleI','artRejI','zsNormI','detrendI','demeanI','blcEnd','nPerm','pSmpl',...
  554. 'conSAv','conSGrAv','conSSe','nConS','conST')
  555. save(append(fileName,'_perm'),'dataAvP_cell','dataGrAvP_cell',...
  556. 'dataDifAvP_cell','dataDifGrAvP_cell','dataSeP_cell','nPerm') % save trial data for permutation in separate file
  557. end
  558. end
  559. end
  560. % copy relevant files to Rep Suppression folder
  561. % curDir = pwd;
  562. % savDir = 'C:\Users\johan\OneDrive\Uni\PhD\MATLAB\ABR2022_Joh\Analysis\Repetition Suppression_Humans';
  563. % copyfile([curDir,'\DD_avData_Oddball_25ms_SbD.mat'],savdir)
  564. % copyfile([curDir,'\DD_avData_Oddball_50ms_SbD.mat'],savdir)
  565. toc
  566. beep