OSCR

Aberrant Neural Entrainment to Word-Level Speech Patterns in Fragile X Syndrome: Evidence for a Statistical Learning Deficit.

Code ↔ Paper

5 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 5 matches
  1. [1] § Methods › EEG Recording and Analysis › Preprocessing ↔ statistical_learning_analysis_scripts.zip/MainITCScript.m, lines 102–134 · score 0.79 · Artifact Blocking, artifact corrected, outer ring, algorithm, threshold, AB
  2. [2] § Methods › EEG Recording and Analysis › Time Course of Neural Entrainment Over Learning ↔ statistical_learning_analysis_scripts.zip/MainITCScript.m, lines 1541–1584 · score 0.62 · ITC pseudovalue, normalized jackknifed, formula, syllable, word
  3. [3] § Methods › EEG Recording and Analysis › Computation of Intertrial Phase Coherence and Statistical Analysis › Scalp‐Level Statistical Analysis ↔ statistical_learning_analysis_scripts.zip/MainITCScript.m, lines 1340–1409 · score 0.61 · Shaded error bars, standard error, scored ITC, syllable frequency, Topographical, word frequency
  4. [4] § Methods › EEG Recording and Analysis › Computation of Intertrial Phase Coherence and Statistical Analysis ↔ statistical_learning_analysis_scripts.zip/MainITCScript.m, lines 1586–1660 · score 0.59 · phase locked, word structure, coherence, epochs, ITC, syllable
  5. [5] § Results › Source‐Level Analysis › Word Entrainment ↔ statistical_learning_analysis_scripts.zip/MainITCScript.m, lines 1340–1409 · score 0.52 · Shaded error bars, standard error, scored ITC, word frequency, zITC, FXS

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 1,661 lines · 74 KB · CC-BY-4.0 · 5 matches

  1. % Apply the Infant Pipeline initially applied in Choi, Batterink 2020 to
  2. % the child data from FXS Project
  3. %datafile_names must remain consistent each time script is run.
  4. %notes
  5. %0770 AB algorithm seemed to create completely tiny voltages - excluded anyway though
  6. %% Read files to analyse
  7. clear % clear matlab workspace
  8. clc % clear matlab command window
  9. CurrentDirectory = '/Volumes/Laura_data/Laura Backup/eeglab 2024/';
  10. cd(CurrentDirectory)
  11. eeglab
  12. %Enter the path of the folder that has the raw data to be analyzed
  13. rawdata_location = [CurrentDirectory 'FXS Project/incoming/structured'];
  14. datafile_names=dir(rawdata_location);
  15. datafile_names=datafile_names(~ismember({datafile_names.name},{'.', '..', '.DS_Store'}));
  16. datafile_names={datafile_names.name};
  17. [filepath,name,ext] = fileparts(char(datafile_names{1}));
  18. %Channel Locations
  19. channel_locations = [CurrentDirectory 'FXS Project/channel location file/GSN-HydroCel-129.sfp'];
  20. %Outer ring of channels:
  21. outerlayer_channel = {'E17' 'E38' 'E43' 'E44' 'E48' 'E49' 'E113' 'E114' 'E119' 'E120' 'E121' 'E125' 'E126' 'E127' 'E128' 'E56' 'E63' 'E68' 'E73' 'E81' 'E88' 'E94' 'E99' 'E107'}; % list of channels
  22. %Codes:
  23. %1-12-10
  24. %11-2-4
  25. %8-3-5
  26. %9-7-6
  27. SyllableCodeStrings = {'DIN1', 'DIN2', 'DIN3', 'DIN4', 'DIN5', 'DIN6', 'DIN7', 'DIN8', 'DIN9', 'DI10', 'DI11', 'DI12', ...
  28. 'D101', 'D102', 'D103', 'D104', 'D105', 'D106', 'D107', 'D108', 'D109', 'D110', 'D111', 'D112'}; %most subjects have the top row of codes, 2310 has bottom row
  29. WordOnsetStrings = {'DIN1', 'DIN8', 'DIN9', 'DI11', ...
  30. 'D101', 'D108', 'D109', 'D111'};
  31. %algorithm parameters for AB algorithm.
  32. threshold = 50; %50 originally; %0 code for didn't apply AB algorithm at all. 999 code for filter from 0.1 to 30 and no alogirthm.
  33. approach = 'total'; %single smoothing matrix used
  34. % ---- Subject Information ---
  35. TDC = {'2481', '1646', '3367', '2860', '1844', '2920', '1136', '2808', '1498', '1655', '2577', '2802', '1343', '1430', ...
  36. '3260', '2181', '1025', '1692', '0076', '0439', '2835', '3186', '0694', '1466', '3107', '2723', '1008', '2313', '1864', '1340', '2805'};
  37. FXS = {'2978', '0836', '1721', '0649', '0468', '0871', '2195', '0913', '1649', '2151', '2472', '2604', '1037', '0392', '1841', '2238', '1798'};
  38. %ASD = {'3463', '2219', '0409', '0502', '0114', '1292', '2410', '2866', '2339', '2100', '0878', '1963','2215', '1995', '2695'};
  39. AllSubjects = [TDC, FXS, ASD];
  40. NewSubjectIDs = {'1798', '1841', '2238', '1963', '1995', '2215', '2695'};
  41. NewSubjectIndices = find(contains(datafile_names, NewSubjectIDs));
  42. AllSubjectIndices = find(contains(datafile_names, [TDC, FXS])); %for now just run TDC and FXS, run ASD later
  43. %% Preprocessing following Fujioka et al. 2011
  44. for subjecti = NewSubjectIndices
  45. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[]; %clear any dataset currently loaded in GUI.
  46. EEG=mff_import([rawdata_location filesep datafile_names{subjecti}]);
  47. [ALLEEG EEG CURRENTSET] = pop_newset( ALLEEG, EEG, CURRENTSET, 'gui','off');
  48. %import channel locations
  49. EEG=pop_chanedit(EEG, 'load',{channel_locations 'filetype' 'autodetect'});
  50. EEG = eeg_checkset( EEG );
  51. % Check whether the channel locations were properly imported. The EEG signals and channel numbers should be same.
  52. if size(EEG.data, 1) ~= length(EEG.chanlocs)
  53. error('The size of the data does not match with channel numbers.');
  54. end
  55. %remove outer ring of channels (see Fujioka et al. 2011)
  56. EEG = pop_select( EEG,'nochannel', outerlayer_channel);
  57. %filter between 0.5 and 20 Hz - same as before.
  58. %ton of 60 hz noise
  59. %filter first with notch, then with buttersworth filter?
  60. EEG = pop_basicfilter( EEG, 1:EEG.nbchan, 'Boundary', 'boundary', 'Cutoff', 60, 'Design', 'notch', 'Filter', 'PMnotch', 'Order', 180, 'RemoveDC', 'on' ); % GUI: 07-Jun-2017 18:55:44
  61. %filter the data using ERPLAB [ 0.5 20]
  62. EEG = pop_basicfilter( EEG, 1:EEG.nbchan, 'Cutoff', [ 0.5 20], 'Design', 'butter', 'Filter', 'bandpass', 'Order', 2, 'RemoveDC', 'on' ); % GUI: 15-Jan-2014 16:49:27
  63. %save the dataset into the appropriate folder
  64. SubjectName = datafile_names{subjecti}(1:4);
  65. EEG.setname = [SubjectName '_preprocessed'];
  66. EEG = pop_saveset( EEG, 'filename', [SubjectName '_preprocessed'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/preprocessed/']); %
  67. end
  68. %% APPLY ARTIFACT BLOCKING (AB) ALGORITHM
  69. for subjecti = NewSubjectIndices
  70. SubjectName = datafile_names{subjecti}(1:4);
  71. %load preprocessed dataset
  72. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  73. EEG = pop_loadset( 'filename', [SubjectName '_preprocessed.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/preprocessed/']);
  74. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  75. %outer ring of channels already removed. %remove CZ - algorithm doesn't
  76. %work if ref channel is included.
  77. EEG = pop_select( EEG,'rmchannel', {'Cz'});
  78. %call algorithm
  79. CleanEEG = AB_alg_window(EEG.data,EEG.srate,threshold, approach); %algorithm won't work properly if ref channel is included.
  80. %EEGDataOriginal = EEG.data;
  81. EEG.data = CleanEEG;
  82. %rerefernce the data - I didn't retain the Cz channel because it gave me an
  83. %warning about the same channel label.
  84. EEG = pop_reref( EEG, []);
  85. %save the dataset into the appropriate folder
  86. EEG.setname = [SubjectName '_artifact corrected'];
  87. EEG = pop_saveset( EEG, 'filename', [SubjectName '_artifact corrected'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/ABCleaned/']); %"real" subjects (not pilot subjects) will be named Infant1, Infant2, Infant3, etc.
  88. end
  89. %% CREATE EPOCHS
  90. NumSyllablesPerEpoch = 30; %syllables as in PsychSci Paper corresponding to 9 seconds.
  91. EpochLength = NumSyllablesPerEpoch*0.3; %in seconds --> this assumes presentation rate of 300ms per syllable
  92. for subjecti = NewSubjectIndices %11:length(datafile_names)
  93. SubjectName = datafile_names{subjecti}(1:4);
  94. %load preprocessed dataset
  95. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  96. EEG = pop_loadset( 'filename', [SubjectName '_artifact corrected.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/ABCleaned/']);
  97. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  98. UnacceptableJitter = 320; %1000hz sampling rate --> 320 msec rather than 300 msec SOA between syllables is not acceptable. Expect 300
  99. EventsToRemove = [];
  100. for x = 2:size(EEG.event,2) %for each code beginning at the second code (first few are start codes anyway)
  101. if strcmp(EEG.event(x).type, 'DI64')
  102. EventsToRemove = [EventsToRemove, x];
  103. end
  104. end
  105. if size(EventsToRemove, 1) > 0
  106. EEG = pop_selectevent( EEG, 'event', EventsToRemove,'select','inverse','deleteevents','on');
  107. end
  108. %epoch to every 10th word (every 30 syllables in the random condition)
  109. y = 5; %don't include the very first syllable due to sharp auditory onset response; skip over three "start codes" plus first syllable
  110. while y < size(EEG.event,2) %number of events
  111. if contains(EEG.event(y).type, WordOnsetStrings) %ismember( EEG.event(y).type, WordOnsetStrings)
  112. CandidateEpochOnset = y; %found a candidate code to onset to.
  113. syllablecounter = 0;
  114. for z = y:size(EEG.event,2) %candidate code is syllable 1, and so on.
  115. %if a pause or break in auditory stimulation is detected
  116. if EEG.event(z).latency - EEG.event(z-1).latency > UnacceptableJitter %155 %unacceptable level of stim jitter or pause. %should typically have an interstim interval of 154 sampling points (300 ms) --> if not, pause is detected (165 originally)
  117. disp('break in auditory stimulation detected!')
  118. disp(EEG.event(z))
  119. syllablecounter = 0; %reset
  120. y = z;
  121. break
  122. end
  123. if contains( EEG.event(z).type, SyllableCodeStrings)
  124. syllablecounter = syllablecounter + 1;
  125. if syllablecounter == NumSyllablesPerEpoch % 36 syllables without running into a boundary or other unexpected code
  126. EEG = pop_editeventvals(EEG,'changefield',{CandidateEpochOnset,'type','NE'});%NE - New Epoch
  127. disp(CandidateEpochOnset)
  128. y = z; %search for next candidate epoch onset 30 positions later.
  129. break
  130. end
  131. elseif ~ismember( EEG.event(z).type, SyllableCodeStrings) %a 'boundary' event --> reset the counter in this case as it needs to be 36 continuous syllables.
  132. disp('other code found')
  133. disp(EEG.event(z).type)
  134. syllablecounter = 0; %reset
  135. y = z; %if you hit a boundary need to start looking again for a candidate epoch onset...
  136. break
  137. end
  138. end
  139. end
  140. y = y + 1;
  141. end
  142. % STEP 12: Segment data into fixed length epochs
  143. %task_event_markers = {'NE'}; %new epoch events, created in step 11.5 (Entrain)
  144. EEG = eeg_checkset(EEG);
  145. EEG = pop_epoch(EEG, {'NE'}, [0 EpochLength], 'epochinfo', 'yes');
  146. EEG = eeg_checkset( EEG );
  147. EEG = pop_rmbase( EEG, [EEG.times(1) EEG.times(end)]); %baseline correct to the entire epoch
  148. EEG = eeg_checkset( EEG );
  149. EEG.setname = [SubjectName '_epoched'];
  150. EEG = pop_saveset( EEG, 'filename', [SubjectName '_epoched'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/epochs/']); %"real" subjects (not
  151. end
  152. %% LOAD PARAMETERS (recommended by Ana) and RUN FFT
  153. % Output frequencies to keep
  154. foutput = [0.6 10];
  155. % Range of frequnecies to use to compute SNR.
  156. % It is better if it includes the foutput and if the lower limit is bigger than the high-pass filter used in the data
  157. fband = [0.2 15];
  158. % target frequencies if indeicated won't be used to compute the SNR.
  159. % Not really necessary, if left empty should give more or less the same
  160. ftarget = []; % [1.11 3.33] | []
  161. % Bins around each frequnecy bin to compute SNR
  162. binsSNR = [-5 -4 -3 -2 -1 1 2 3 4 5];
  163. % SNR method for the power
  164. % based on the linear fit of log(Power) vs log(freq) of the adjacent
  165. % freuency bins. it seems the most sensitive
  166. typeSNRPWR = 'linear';
  167. % SNR method for the PLV
  168. % In principle it shouldn't be necessary but by computing it sensitivity
  169. % may slightly improve. I put 'none' but you can try 'linear' or 'mean'
  170. typeSNRPLV = 'none';
  171. % Z-score or not the final power.
  172. % Not really necessary, only to center at zero the final data
  173. zscorePWR = 0;
  174. % Z-score or not the final PLV.
  175. % Not really necessary, only to center at zero the final data
  176. zscorePLV = 0;
  177. cd([CurrentDirectory 'FXS Project/infant pipeline/FFT files/']) %so that files go in proper place
  178. DataQualityMtx = [];
  179. for subjecti= NewSubjectIndices %1:length(datafile_names)
  180. clear EEGfrq
  181. SubjectName = datafile_names{subjecti}(1:4);
  182. %load dataset
  183. %load preprocessed dataset
  184. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  185. EEG = pop_loadset( 'filename', [SubjectName '_epoched.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/epochs/']);
  186. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  187. EEGfrq = frqa_plvpwr(EEG, 'foutput',foutput,'fband',fband,'binsSNR',binsSNR,...
  188. 'typeSNRPWR',typeSNRPWR,'typeSNRPLV',typeSNRPLV,...
  189. 'zscorePWR',zscorePWR,'zscorePLV',zscorePLV);
  190. filename = char(strcat(SubjectName, '_Structured_EEGfreq'));
  191. save(filename, 'EEGfrq'); %how to save when filename is a variable set beforehand
  192. end
  193. %% Individual FFT plots
  194. FFTfile_location = [CurrentDirectory 'FXS Project/infant pipeline/FFT files'];
  195. cd(FFTfile_location)
  196. %FFTfiles = dir('*Structured_EEGfreq.mat'); %this only considers the files that were succesfully preprocessed and not those tagged with 'no usable data, all bad epochs.'
  197. %FFTfile_names={FFTfiles.name};
  198. plotchan= 1:104; % we removed the outer ring of electrodes
  199. locsfile = [CurrentDirectory 'FXS Project/channel location file/EGI104InnerChannelsNoCz.locs']; %exported this .locs file one time from EEG dataset. writelocs( chanstruct, filename ); writelocs( EEG.chanlocs, 'testlocs' );
  200. for subji = NewSubjectIndices %1:length(FFTfile_names)
  201. cd([CurrentDirectory 'FXS Project/infant pipeline/FFT files'])
  202. %Load struct_ersp and rand_ersp for each subject
  203. clear Struct_PLV EEGfrq*
  204. SubjectName = datafile_names{subji}(1:4);
  205. %SubjectNumber = extractBetween(FFTfile_names{subji}, 1, 4);
  206. load([SubjectName '_Structured_EEGfreq.mat'])
  207. %load(FFTfile_names{subji})
  208. Struct_PLV = EEGfrq.plv(:,:);
  209. freqvals = EEGfrq.freqs; %freqs based on last file loaded
  210. freqvalindicesunder5Hz = find(freqvals <= 5);
  211. [~, WordFreq] = min(abs(freqvals-1.1111));
  212. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  213. %extract neighbouring bins
  214. NeighbouringWordFreqBins = [WordFreq-3, WordFreq-2, WordFreq-1, WordFreq+1, WordFreq+2, WordFreq+3];
  215. NeighbouringSyllableFreqBins = [SyllableFreq-3, SyllableFreq-2, SyllableFreq-1, SyllableFreq+1, SyllableFreq+2, SyllableFreq+3];
  216. %compute actual and normalized ITC values for topoplot
  217. WordITC = Struct_PLV(plotchan, WordFreq);
  218. SyllableITC = Struct_PLV(plotchan, SyllableFreq);
  219. WordNeighboursITC = squeeze(mean(Struct_PLV(plotchan, NeighbouringWordFreqBins ),2));
  220. SyllableNeighboursITC = squeeze(mean(Struct_PLV(plotchan, NeighbouringSyllableFreqBins ),2));
  221. WordITCNormalized = WordITC - WordNeighboursITC;
  222. SyllableITCNormalized = SyllableITC - SyllableNeighboursITC;
  223. cd([CurrentDirectory 'FXS Project/infant pipeline/individual plots'])
  224. figure; plot(freqvals(freqvalindicesunder5Hz), mean(Struct_PLV(plotchan,freqvalindicesunder5Hz),1), 'r');
  225. hold on
  226. xline(1.111, '--')
  227. hold on
  228. xline(2.222, '--')
  229. hold on
  230. xline(3.333, '--')
  231. hold on
  232. legend([SubjectName ' structured'])
  233. figurename = char(strcat(SubjectName, '_Structured'));
  234. print('-dpdf', figurename); %save as postscript in order to merge two files
  235. %topoplot
  236. WordFreqScaleLimits = [-0.25 .25];
  237. SyllableFreqScaleLimits = [-0.6 0.6];
  238. figure;
  239. subplot(2,2,1); topoplot(WordITC, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits , 'shading','interp'); colorbar;
  240. title([SubjectName 'ITC Word Frequency']);
  241. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  242. subplot(2,2,2); topoplot(SyllableITC, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits , 'shading','interp'); colorbar;
  243. title('ITC Syllable Frequency');
  244. subplot(2,2,3); topoplot(WordITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits , 'shading','interp'); colorbar;
  245. title('Normalized ITC Word Frequency');
  246. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  247. subplot(2,2,4); topoplot(SyllableITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits , 'shading','interp'); colorbar;
  248. title('Normalized ITC Syllable Frequency');
  249. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  250. filename = char(strcat(SubjectName, ' ITC Topoplot'));
  251. print ('-dtiff', filename);
  252. end
  253. %% GRAND AVERAGE - FFT -- ALL PARTICIPANTS - OVERALL EXPOSURE
  254. clear SubjectIDs ITCVars
  255. clear FFTfile* Structured_PLVMtx
  256. clear Structured_PLVMtx
  257. plotchan= 1:104; %SigWordElectrodes; %1:105; % we removed the outer ring of electrodes
  258. locsfile = [CurrentDirectory 'FXS Project/channel location file/EGI104InnerChannelsNoCz.locs']; %exported this .locs file one time from EEG dataset. writelocs( chanstruct, filename ); writelocs( EEG.chanlocs, 'testlocs' );
  259. FFTfile_location = [CurrentDirectory 'FXS Project/infant pipeline/FFT files'];
  260. cd(FFTfile_location)
  261. FFTfiles = dir('*Structured_EEGfreq.mat'); %this only considers the files that were succesfully preprocessed and not those tagged with 'no usable data, all bad epochs.'
  262. FFTfile_names={FFTfiles.name};
  263. SubjectList = [];
  264. GroupName = ASD; %FXS; %TDC; %FXS; %ASD %TDC; %ASD; %FXS; %TDC; %FXS; %TDC; AllSubjects; %
  265. %get subject list
  266. for x = 1:length(FFTfile_names)
  267. SubjectNumber = cell2mat(extractBetween(FFTfile_names{x}, 1, 4));
  268. if ismember(SubjectNumber, GroupName)
  269. SubjectList = [SubjectList, x];
  270. end
  271. end
  272. % -- STRUCTURED --
  273. clear PLVMtx Struct* Rand* Grand* PLV*
  274. for i = SubjectList
  275. display(i)
  276. %Load struct_ersp and rand_ersp for each subject
  277. %load([SubjectID{i} '_EEGfrq.mat'])
  278. load(FFTfile_names{i})
  279. disp(FFTfile_names{i})
  280. PLV = EEGfrq.plv(plotchan,:); %only extracts relevant channels
  281. Structured_PLVMtx(i,:,:) = PLV; %rows without corresponding subjects (e.g., 20) just contains 0s. This is taken into account below by selecting SubjectsToInclude as a dimension.
  282. % -- to extract individual level variables --
  283. freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  284. [~, WordFreq] = min(abs(freqvals-1.1111));
  285. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  286. %extract neighbouring bins
  287. NeighbouringWordFreqBins = [WordFreq-3, WordFreq-2, WordFreq-1, WordFreq+1, WordFreq+2, WordFreq+3];
  288. NeighbouringSyllableFreqBins = [SyllableFreq-3, SyllableFreq-2, SyllableFreq-1, SyllableFreq+1, SyllableFreq+2, SyllableFreq+3];
  289. %compute individual actual and normalized ITC values to store for analysis
  290. WordITC = PLV(:, WordFreq);
  291. SyllableITC = PLV(:, SyllableFreq);
  292. WordNeighboursITC = squeeze(mean(PLV(:, NeighbouringWordFreqBins ),2));
  293. SyllableNeighboursITC = squeeze(mean(PLV(:, NeighbouringSyllableFreqBins ),2));
  294. WordITCNormalized = WordITC - WordNeighboursITC;
  295. SyllableITCNormalized = SyllableITC - SyllableNeighboursITC;
  296. %average across channels
  297. MeanWordITC = mean(WordITC,1);
  298. MeanSyllableITC = mean(SyllableITC,1);
  299. MeanWordITCNormalized = mean(WordITCNormalized,1);
  300. MeanSyllableITCNormalized = mean(SyllableITCNormalized,1);
  301. ITCVars(i,:,:,:) = [MeanWordITC, MeanSyllableITC, MeanWordITCNormalized, MeanSyllableITCNormalized];
  302. %store subject and group information
  303. SubjectNumber = cell2mat(extractBetween(FFTfile_names{i}, 1, 4));
  304. if ismember(SubjectNumber, TDC)
  305. GroupNum = 1;
  306. elseif ismember(SubjectNumber, FXS)
  307. GroupNum = 2;
  308. elseif ismember(SubjectNumber, ASD)
  309. GroupNum = 3;
  310. end
  311. SubjectIDs{i,1} = SubjectNumber;
  312. SubjectIDs{i,2} = GroupNum; %also store group membership
  313. %CongruentSubjectIDs{i,:} = SubjectID{i};
  314. end
  315. %freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  316. %average across channels
  317. GrandAveragePLV_Structured = squeeze(mean(Structured_PLVMtx(SubjectList,:,:),1));
  318. GrandAveragePLV_avacrosschans_Structured = mean(GrandAveragePLV_Structured(:,:),1);
  319. %Standard Error
  320. PLV_averageacrosschans_Structured = squeeze(mean(Structured_PLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  321. STD_Structured = std(PLV_averageacrosschans_Structured(:,:)); %nfreqs
  322. SE_Structured = STD_Structured/sqrt(numel(SubjectList));
  323. NSubjects = numel(SubjectList);
  324. %---- Plots ------
  325. cd([CurrentDirectory 'FXS Project/infant pipeline/grand averages/'])
  326. %truncated
  327. freqvalindicesunder5Hz = find(freqvals <= 5);
  328. figure; plot(freqvals(freqvalindicesunder5Hz), GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz),'r');
  329. hold on
  330. %shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), 'lineprops','r') %old syntax for shadedErrorBar
  331. shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), {'Color', 'r' }, 1);
  332. hold on
  333. xline(1.111, '--')
  334. hold on
  335. xline(2.222, '--')
  336. hold on
  337. xline(3.333, '--')
  338. legend('structured', 'SE')
  339. pdfname = ['ITC FFT All Channels, n = ' num2str(NSubjects)];
  340. %pdfname = ['ITC FFT Auditory ROI'];
  341. print('-dpdf', pdfname); %save as postscript in order to merge two files
  342. % PLOT TOPOS
  343. %figure out freqs of interest
  344. [~, WordFreq] = min(abs(freqvals-1.1111));
  345. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  346. %extract neighbouring bins
  347. NeighbouringWordFreqBins = [WordFreq-3, WordFreq-2, WordFreq-1, WordFreq+1, WordFreq+2, WordFreq+3];
  348. NeighbouringSyllableFreqBins = [SyllableFreq-3, SyllableFreq-2, SyllableFreq-1, SyllableFreq+1, SyllableFreq+2, SyllableFreq+3];
  349. Structured_ITC_WordFreq = squeeze(GrandAveragePLV_Structured(:,WordFreq));
  350. Structured_ITC_SyllableFreq = squeeze(GrandAveragePLV_Structured(:,SyllableFreq));
  351. WordNeighboursITC = squeeze(mean(GrandAveragePLV_Structured(:, NeighbouringWordFreqBins ),2));
  352. SyllableNeighboursITC = squeeze(mean(GrandAveragePLV_Structured(:, NeighbouringSyllableFreqBins ),2));
  353. WordITCNormalized = Structured_ITC_WordFreq - WordNeighboursITC;
  354. SyllableITCNormalized = Structured_ITC_SyllableFreq - SyllableNeighboursITC;
  355. WordFreqScaleLimits = [-0.2 .2];
  356. SyllableFreqScaleLimits = [-0.5 0.5];
  357. NormalizedWordFreqScaleLimits = [-0.05 .05];
  358. NormalizedSyllableFreqScaleLimits = [-0.4 0.4];
  359. PValueLimits = [0 0.1];
  360. figure;
  361. %regular raw values
  362. subplot(2,2,1); topoplot(Structured_ITC_WordFreq, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits , 'shading','interp'); colorbar;
  363. title('Structured ITC Word Frequency');
  364. subplot(2,2,2); topoplot(Structured_ITC_SyllableFreq, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits , 'shading','interp'); colorbar;
  365. title('Structured ITC Syllable Frequency');
  366. %normalized
  367. subplot(2,2,3); topoplot(WordITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', NormalizedWordFreqScaleLimits , 'shading','interp'); colorbar;
  368. title('ITC Word Normalized');
  369. subplot(2,2,4); topoplot(SyllableITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', NormalizedSyllableFreqScaleLimits , 'shading','interp'); colorbar;
  370. title('ITC Syllable Normalized');
  371. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  372. filename = ['Condition x Frequency Topo Plots n = ' num2str(NSubjects)];
  373. print ('-dtiff', filename);
  374. %figure out which electrodes are significant
  375. NormalizedWordITC_SubjectByChannel = Structured_PLVMtx(SubjectList,:,WordFreq) - mean(Structured_PLVMtx(SubjectList,:,NeighbouringWordFreqBins),3); %NSubject x NChan
  376. NormalizedSyllableITC_SubjectByChannel = Structured_PLVMtx(SubjectList,:,SyllableFreq) - mean(Structured_PLVMtx(SubjectList,:,NeighbouringSyllableFreqBins),3);
  377. [SigWordElectrodesArray, PWord] = ttest(NormalizedWordITC_SubjectByChannel, 0, 'tail', 'right'); %one directional t-test, mean is greater than 0
  378. [SigSyllableElectrodesArray, PSyllable] = ttest(NormalizedSyllableITC_SubjectByChannel, 0, 'tail', 'right'); %one directional t-test, mean is greater than 0
  379. SigWordElectrodes = find(SigWordElectrodesArray ==1);
  380. SigSyllableElectrodes = find(SigSyllableElectrodesArray ==1);
  381. NumSigWordElectrodes = numel(SigWordElectrodes);
  382. %plot significant electrodes
  383. figure;
  384. subplot(1,2,1)
  385. topoplot(WordITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', NormalizedWordFreqScaleLimits,'shading','interp', 'emarker2', {SigWordElectrodes ,'p','k', 7, 1} ); colorbar;
  386. title(['Significant Word ITC Electrodes: ' num2str(NumSigWordElectrodes)]);
  387. subplot(1,2,2)
  388. topoplot(SyllableITCNormalized, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', NormalizedSyllableFreqScaleLimits,'shading','interp', 'emarker2', {SigSyllableElectrodes ,'p','k', 7, 1} ); colorbar;
  389. title(['Significant Syllable ITC Electrodes']);
  390. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  391. filename = ['Sig Electrodes Topo Plots n = ' num2str(NSubjects)];
  392. print ('-dtiff', filename);
  393. %if you want you could run it from the top one more time to plot the ITC
  394. %graph with only the significant word electrodes
  395. % %create a table
  396. % ITCVarsCell = num2cell(ITCVars);
  397. % ITCVarsWithSubjectIDs = horzcat(SubjectIDs, ITCVarsCell);
  398. %
  399. % ColumnNames = {'Subject', 'Group', 'WordITC', 'SyllableITC', 'WordITCNormalized', 'SyllableITCNormalized'};
  400. % IndividualLevelVariablesTableForAnalysis = cell2table(ITCVarsWithSubjectIDs(1:end,:), 'VariableNames', ColumnNames);
  401. %
  402. % LocationForCSV = [CurrentDirectory 'FXS Project/infant pipeline/grand averages/stats for analysis']; %on the server
  403. % cd(LocationForCSV)
  404. %
  405. % writetable(IndividualLevelVariablesTableForAnalysis,'IndividualLevelVariablesTableForAnalysis.csv')
  406. %% CREATE 100 SURROGATE DATASETS PER PARTICIPANT
  407. %load the same FFT parameters as above.
  408. EpochLength = 9;
  409. cd([CurrentDirectory 'FXS Project/infant pipeline/shuffled FFT files/']) %so that files go in proper place
  410. NumIterations = 100;
  411. for subjecti = 1:length(datafile_names)
  412. clear EEGfrq_ByIteration
  413. disp(subjecti)
  414. %load dataset
  415. SubjectName = datafile_names{subjecti}(1:4);
  416. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  417. EEG = pop_loadset( 'filename', [SubjectName '_epoched.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/epochs/']);
  418. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  419. %for each 200 "actual onset" event code, get the "urevent" - in EGI, this
  420. %is stored as EEG.event.description
  421. %double check to make sure each epoch has the correct number of events
  422. OnsetCodeStrings = {'NE'};
  423. EventDescriptionMtx = [];
  424. for x = 1:size(EEG.event,2) %epoch
  425. if ismember( EEG.event(x).type, OnsetCodeStrings )
  426. EventDescription = str2double(EEG.event(x).description);
  427. EventDescriptionMtx = [EventDescriptionMtx, EventDescription];
  428. end
  429. end
  430. EventDescriptionMtxUnique = unique(EventDescriptionMtx); %remove duplicates
  431. %load preprocessed AB corrected continuous data
  432. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  433. EEG = pop_loadset( 'filename', [SubjectName '_artifact corrected.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/ABCleaned/']);
  434. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  435. ParentEEG = EEG; %parentEEG will now be used for all iterations
  436. %for each iteration
  437. for iter = 1:NumIterations
  438. disp(iter)
  439. %for each UR Event identified above (corresponding to a 200 code), randomly select an onset from -1 to 1 seconds before or
  440. %after to shuffle the timing while preserving the general sleep state
  441. DatapointLength = 1000/EEG.srate;
  442. %plus or minus 900 ms (word rate) from the true event
  443. ShufflingWindowMin = -1*900/(DatapointLength); % -900;
  444. ShufflingWindowMax = 900/(DatapointLength); %+900 datapoints (EEG.srate = 1000).
  445. EventsToAdd = [];
  446. for x = 1:size(ParentEEG.event,2) %number of events
  447. if ismember( str2double(ParentEEG.event(x).description), EventDescriptionMtxUnique)
  448. %randomly select an interval +/- 1.0 seconds
  449. RandomInterval = ShufflingWindowMin + (ShufflingWindowMax-ShufflingWindowMin).*rand(1); %in data points
  450. ShuffledOnsetLatency = ParentEEG.event(x).latency + RandomInterval; %in datapoints
  451. EventsToAdd = [EventsToAdd; 300, ShuffledOnsetLatency];
  452. end
  453. end
  454. %insert new events (300 codes) that are +/- 900 msec prior to the real onsets
  455. EEG = pop_importevent(ParentEEG, 'event', EventsToAdd, 'fields', {'type', 'latency'}, 'append', 'yes', 'optimalign', 'off', 'timeunit', NaN ); %datapoints
  456. EEG = eeg_checkset( EEG );
  457. %epoch to all 300 codes.
  458. EEG = pop_epoch( EEG, { '300'}, [0 EpochLength], 'epochinfo', 'yes'); %epoch all the selected events.
  459. EEG = eeg_checkset( EEG );
  460. EEG = pop_rmbase( EEG, [EEG.times(1) EEG.times(end)]); %baseline correct to the entire epoch (better for running ICA).
  461. EEG = eeg_checkset( EEG );
  462. %double check to make sure each epoch has the correct number of events
  463. for x = 1:size(EEG.epoch,2) %epoch
  464. NumSyllables = 0; %each epoch should have 30 or 31 syllables exactly (31 because the next syllable might just make it into the epoch)
  465. for y = 1:size(EEG.epoch(x).event,2) %event within each epoch
  466. if ismember( EEG.epoch(x).eventtype{y}, SyllableCodeStrings )
  467. NumSyllables = NumSyllables + 1;
  468. end
  469. end
  470. if NumSyllables <30|| NumSyllables >31
  471. disp(['Epoch Error! Epoch to Remove:' num2str(x) ])
  472. disp(['Epoch as only ' num2str(NumSyllables) ' syllable codes, which can happen at the end of a naturally occurring block.'])
  473. else
  474. disp('All epochs contain the expected number of syllable codes!')
  475. end
  476. end
  477. %run FFT
  478. clear EEGfrq
  479. EEGfrq = frqa_plvpwr(EEG, 'foutput',foutput,'fband',fband,'binsSNR',binsSNR,...
  480. 'typeSNRPWR',typeSNRPWR,'typeSNRPLV',typeSNRPLV,...
  481. 'zscorePWR',zscorePWR,'zscorePLV',zscorePLV);
  482. %for the first iteration ONLY, create the big structure
  483. %this will be filled in eventually with all iterations
  484. if iter == 1
  485. EEGfrq_ByIteration.iteration(1:NumIterations) = EEGfrq; %in order to have a bigger structure with the same structure
  486. disp('creating the big structure for all subsequent iterations...')
  487. end
  488. EEGfrq_ByIteration.iteration(iter) = EEGfrq;
  489. end %end final iteration
  490. % save the big structure
  491. filename = char(strcat(SubjectName, '_EEGfreq_ByIteration'));
  492. save(filename, 'EEGfrq_ByIteration'); %how to save when filename is a variable set beforehand
  493. end
  494. %% EXTRACT PLV FROM TRUE DATA AND SURROGATE DATA, AND PLOT
  495. clear SubjectIDs ITCVars
  496. clear FFTfile* Structured_PLVMtx
  497. clear Structured_PLVMtx
  498. plotchan= 1:104; %SigWordElectrodes; %1:105; % we removed the outer ring of electrodes
  499. locsfile = [CurrentDirectory 'FXS Project/channel location file/EGI104InnerChannelsNoCz.locs']; %exported this .locs file one time from EEG dataset. writelocs( chanstruct, filename ); writelocs( EEG.chanlocs, 'testlocs' );
  500. FFTfile_location = [CurrentDirectory 'FXS Project/infant pipeline/FFT files'];
  501. cd(FFTfile_location)
  502. FFTfiles = dir('*Structured_EEGfreq.mat'); %this only considers the files that were succesfully preprocessed and not those tagged with 'no usable data, all bad epochs.'
  503. FFTfile_names={FFTfiles.name};
  504. FFTsurrogatefile_location = [CurrentDirectory 'FXS Project/infant pipeline/shuffled FFT files'];
  505. SubjectList = [];
  506. GroupName = FXS; %ASD %TDC; %ASD; %FXS; %TDC; %FXS; %TDC; AllSubjects; %
  507. %get subject list
  508. for x = 1:length(FFTfile_names)
  509. SubjectNumber = cell2mat(extractBetween(FFTfile_names{x}, 1, 4));
  510. if ismember(SubjectNumber, GroupName)
  511. SubjectList = [SubjectList, x];
  512. end
  513. end
  514. % -- STRUCTURED --
  515. clear PLVMtx Struct* Rand* Grand* PLV*
  516. TruePLVMtx = [];
  517. SurrogatePLVMtx = [];
  518. PLVSurrogate = [];
  519. for i = SubjectList
  520. clear EEGfrq* SurrogateDataFileName SurrogateDatasetsMtx
  521. display(i)
  522. %load "true" data
  523. cd(FFTfile_location)
  524. load(FFTfile_names{i})
  525. disp(FFTfile_names{i})
  526. PLVTrue = EEGfrq.plv(plotchan,:); %only extracts relevant channels
  527. TruePLVMtx(i,:,:) = PLVTrue; %rows without corresponding subjects (e.g., 20) just contains 0s. This is taken into account below by selecting SubjectsToInclude as a dimension.
  528. %load corresponding surrogate data
  529. cd(FFTsurrogatefile_location)
  530. SurrogateDataFileName = [char(extractBetween(FFTfile_names{i}, 1,4)) '_EEGfreq_ByIteration.mat'];
  531. load(SurrogateDataFileName)
  532. for iterationnum = 1:size(EEGfrq_ByIteration.iteration,2)
  533. SurrogateDatasetsMtx(iterationnum,:,:) = EEGfrq_ByIteration.iteration(iterationnum).plv(plotchan,:); %nchan x nfreqs for each surrogate dataset; ndataset x nchan x nfreq
  534. end
  535. PLVSurrogate = squeeze(mean(SurrogateDatasetsMtx,1)); %average across the 5 surrogate datasets for the subject
  536. SurrogatePLVMtx(i,:,:) = PLVSurrogate ; %nchan x nfreqs
  537. end
  538. % -- to extract individual level variables --
  539. freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  540. [~, WordFreq] = min(abs(freqvals-1.1111));
  541. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  542. GrandAverageTruePLV = squeeze(mean(TruePLVMtx(SubjectList,:,:),1));
  543. GrandAverageTruePLV_avacrosschans = mean(GrandAverageTruePLV(:,:),1);
  544. GrandAverageSurrogatePLV = squeeze(mean(SurrogatePLVMtx(SubjectList,:,:),1));
  545. GrandAverageSurrogatePLV_avacrosschans = mean(GrandAverageSurrogatePLV(:,:),1);
  546. %Standard Error
  547. TruePLV_averageacrosschans = squeeze(mean(TruePLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  548. STD_TruePLV = std(TruePLV_averageacrosschans(:,:)); %nfreqs
  549. SE_TruePLV = STD_TruePLV /sqrt(numel(SubjectList));
  550. SurrogatePLV_averageacrosschans = squeeze(mean(SurrogatePLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  551. STD_SurrogatePLV = std(SurrogatePLV_averageacrosschans(:,:)); %nfreqs
  552. SE_SurrogatePLV = STD_SurrogatePLV /sqrt(numel(SubjectList));
  553. NSubjects = numel(SubjectList);
  554. %---- Plots ------
  555. cd([CurrentDirectory 'FXS Project/infant pipeline/grand averages/'])
  556. %truncated
  557. freqvalindicesunder5Hz = find(freqvals <= 5);
  558. figure; plot(freqvals(freqvalindicesunder5Hz), GrandAverageTruePLV_avacrosschans(freqvalindicesunder5Hz),'r');
  559. hold on
  560. %shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), 'lineprops','r') %old syntax for shadedErrorBar
  561. shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAverageTruePLV_avacrosschans(freqvalindicesunder5Hz), SE_TruePLV(freqvalindicesunder5Hz), {'Color', 'r' }, 1);
  562. hold on
  563. plot(freqvals(freqvalindicesunder5Hz), GrandAverageSurrogatePLV_avacrosschans(freqvalindicesunder5Hz),'b');
  564. hold on
  565. shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAverageSurrogatePLV_avacrosschans(freqvalindicesunder5Hz), SE_SurrogatePLV(freqvalindicesunder5Hz), {'Color', 'b' }, 1);
  566. hold on
  567. xline(1.111, '--')
  568. hold on
  569. xline(2.222, '--')
  570. hold on
  571. xline(3.333, '--')
  572. legend('structured', 'SE', 'surrogate', 'SE')
  573. pdfname = ['ITC FFT True data versus Surrogate data, All Channels, n = ' num2str(NSubjects)];
  574. %pdfname = ['ITC FFT Auditory ROI'];
  575. print('-dpdf', pdfname); %save as postscript in order to merge two files
  576. % plot distribution
  577. WordFreqScaleLimits = [-0.25 0.25]; %[-0.15 .15]; %so that 0 is centered on green.
  578. SyllableFreqScaleLimits = [-0.5 .5];
  579. DifferenceEffectScaleLimits = [-0.05 0.05];
  580. figure;
  581. subplot(2,2,1)
  582. topoplot(GrandAverageTruePLV(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  583. title('True Data, Word Frequency');
  584. subplot(2,2,2)
  585. topoplot(GrandAverageTruePLV(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  586. title('True Data, Syllable Frequency');
  587. subplot(2,2,3)
  588. topoplot(GrandAverageSurrogatePLV(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  589. title('Surrogate Data, Word Frequency');
  590. subplot(2,2,4)
  591. topoplot(GrandAverageSurrogatePLV(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  592. title('Surrogate Data, Syllable Frequency');
  593. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  594. filename = ['Topographical Distributions, True versus Surrogate, n = ' num2str(NSubjects)];
  595. print ('-dtiff', filename);
  596. %difference topo
  597. WordFreqDifference = GrandAverageTruePLV(:,WordFreq) - GrandAverageSurrogatePLV(:,WordFreq);
  598. SyllableFreqDifference = GrandAverageTruePLV(:,SyllableFreq) - GrandAverageSurrogatePLV(:,SyllableFreq);
  599. % figure;
  600. % subplot(2,2,1)
  601. % %topoplot(WordFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', DifferenceEffectScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  602. % topoplot(WordFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', DifferenceEffectScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp', 'emarker2', {SignificantElectrodes_Word ,'p','k', 10, 1}); colorbar;
  603. % title('True minus Surrogate, Word Frequency');
  604. % subplot(2,2,2)
  605. % %topoplot(SyllableFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  606. % topoplot(SyllableFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp', 'emarker2', {SignificantElectrodes_Syllable,'p','k', 10, 1}); colorbar;
  607. % title('True minus Surrogate, Syllable Frequency');
  608. % set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  609. % filename = ['Topographical Distributions, True versus Surrogate, Difference, Sig Electrodes'];
  610. % print ('-dtiff', filename);
  611. figure;
  612. subplot(2,2,1)
  613. topoplot(WordFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', DifferenceEffectScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  614. %topoplot(WordFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', DifferenceEffectScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp', 'emarker2', {SignificantElectrodes_Word ,'p','k', 10, 1}); colorbar;
  615. title('True minus Surrogate, Word Frequency');
  616. subplot(2,2,2)
  617. topoplot(SyllableFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  618. %topoplot(SyllableFreqDifference, locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp', 'emarker2', {SignificantElectrodes_Syllable,'p','k', 10, 1}); colorbar;
  619. title('True minus Surrogate, Syllable Frequency');
  620. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  621. title('True minus Surrogate, Syllable Frequency');
  622. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  623. filename = ['Topographical Distributions, True versus Surrogate, Difference, n = ' num2str(NSubjects)];
  624. print ('-dtiff', filename);
  625. %% EXTRACT PLV FROM TRUE DATA AND SURROGATE DATA, AND PLOT AS Z SCORES
  626. clear SubjectIDs ITCVars
  627. clear FFTfile* Structured_PLVMtx
  628. clear Structured_PLVMtx
  629. plotchan= 1:104; %SigWordElectrodes; %1:105; % we removed the outer ring of electrodes
  630. locsfile = [CurrentDirectory 'FXS Project/channel location file/EGI104InnerChannelsNoCz.locs']; %exported this .locs file one time from EEG dataset. writelocs( chanstruct, filename ); writelocs( EEG.chanlocs, 'testlocs' );
  631. FFTfile_location = [CurrentDirectory 'FXS Project/infant pipeline/FFT files'];
  632. cd(FFTfile_location)
  633. FFTfiles = dir('*Structured_EEGfreq.mat'); %this only considers the files that were succesfully preprocessed and not those tagged with 'no usable data, all bad epochs.'
  634. FFTfile_names={FFTfiles.name};
  635. FFTsurrogatefile_location = [CurrentDirectory 'FXS Project/infant pipeline/shuffled FFT files'];
  636. SubjectList = [];
  637. SubjectIDList = []; %for bookkeeping for later analyses
  638. GroupName = ASD; %FXS; %TDC; %FXS; %TDC; AllSubjects; %
  639. %get subject list
  640. for x = 1:length(FFTfile_names)
  641. SubjectNumber = cell2mat(extractBetween(FFTfile_names{x}, 1, 4));
  642. if ismember(SubjectNumber, GroupName)
  643. SubjectList = [SubjectList, x];
  644. SubjectIDList = [SubjectIDList; str2double(SubjectNumber)];
  645. end
  646. end
  647. % -- STRUCTURED --
  648. clear PLVMtx Struct* Rand* Grand* PLV*
  649. TruePLVMtx = [];
  650. PLVSurrogate = [];
  651. SurrogatePLVMtx = [];
  652. zscoreTruePLVMtx = [];
  653. for i = SubjectList
  654. clear EEGfrq* SurrogateDataFileName SurrogateDatasetsMtx zscoreTruePLV
  655. display(i)
  656. %load "true" data
  657. cd(FFTfile_location)
  658. load(FFTfile_names{i})
  659. disp(FFTfile_names{i})
  660. PLVTrue = EEGfrq.plv(plotchan,:); %only extracts relevant channels
  661. TruePLVMtx(i,:,:) = PLVTrue; %rows without corresponding subjects (e.g., 20) just contains 0s. This is taken into account below by selecting SubjectsToInclude as a dimension.
  662. %load corresponding surrogate data
  663. cd(FFTsurrogatefile_location)
  664. SurrogateDataFileName = [char(extractBetween(FFTfile_names{i}, 1,4)) '_EEGfreq_ByIteration.mat'];
  665. load(SurrogateDataFileName)
  666. for iterationnum = 1:size(EEGfrq_ByIteration.iteration,2)
  667. SurrogateDatasetsMtx(iterationnum,:,:) = EEGfrq_ByIteration.iteration(iterationnum).plv(plotchan,:); %nchan x nfreqs for each surrogate dataset; ndataset x nchan x nfreq
  668. end
  669. % Z score the data according to the surrogate distribution
  670. % each subject serves as their own Z score distribution
  671. Mean_Surrogate = squeeze(mean(SurrogateDatasetsMtx,1)); %average across the 100 surrogate datasets for the subject
  672. STD_Surrogate = squeeze(std(SurrogateDatasetsMtx)); %std deviation
  673. %compute z score
  674. zscoreTruePLV = (PLVTrue - Mean_Surrogate) ./ STD_Surrogate;
  675. SurrogatePLVMtx(i,:,:) = Mean_Surrogate; %stores the mean surrogate ITCs for each subject; nregion x nfreqs
  676. zscoreTruePLVMtx(i,:,:) = zscoreTruePLV; %stores the z scored actual observed data for each subject, nregion x nfreqs
  677. end
  678. % -- to extract individual level variables --
  679. freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  680. [~, WordFreq] = min(abs(freqvals-1.1111));
  681. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  682. GrandAverageTruePLV = squeeze(mean(TruePLVMtx(SubjectList,:,:),1));
  683. GrandAverageTruePLV_avacrosschans = mean(GrandAverageTruePLV(:,:),1);
  684. GrandAverageSurrogatePLV = squeeze(mean(SurrogatePLVMtx(SubjectList,:,:),1));
  685. GrandAverageSurrogatePLV_avacrosschans = mean(GrandAverageSurrogatePLV(:,:),1);
  686. %Standard Error
  687. TruePLV_averageacrosschans = squeeze(mean(TruePLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  688. STD_TruePLV = std(TruePLV_averageacrosschans(:,:)); %nfreqs
  689. SE_TruePLV = STD_TruePLV /sqrt(numel(SubjectList));
  690. SurrogatePLV_averageacrosschans = squeeze(mean(SurrogatePLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  691. STD_SurrogatePLV = std(SurrogatePLV_averageacrosschans(:,:)); %nfreqs
  692. SE_SurrogatePLV = STD_SurrogatePLV /sqrt(numel(SubjectList));
  693. %Z scores
  694. GrandAverageZscore = squeeze(mean(zscoreTruePLVMtx(SubjectList,:,:),1)); %nelectrodes x nfreqs
  695. GrandAverageZscore_avacrosselectrodes = mean(GrandAverageZscore,1); %across all electrodes
  696. %standard error
  697. ZScoreTruePLV_averageacrosschans = squeeze(mean(zscoreTruePLVMtx(SubjectList,:,:),2)); %now nsubj x nfreq
  698. STD_ZScoreTruePLV = std(ZScoreTruePLV_averageacrosschans(:,:)); %nfreqs
  699. SE_ZScoreTruePLV = STD_ZScoreTruePLV /sqrt(numel(SubjectList));
  700. NSubjects = numel(SubjectList);
  701. %---- Plots ------
  702. cd([CurrentDirectory 'FXS Project/infant pipeline/grand averages/z scored grand averages/'])
  703. %truncated
  704. freqvalindicesunder5Hz = find(freqvals <= 5);
  705. %this is the same plot as created in the above cell
  706. % figure; plot(freqvals(freqvalindicesunder5Hz), GrandAverageTruePLV_avacrosschans(freqvalindicesunder5Hz),'r');
  707. % hold on
  708. % %shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), 'lineprops','r') %old syntax for shadedErrorBar
  709. % shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAverageTruePLV_avacrosschans(freqvalindicesunder5Hz), SE_TruePLV(freqvalindicesunder5Hz), {'Color', 'r' }, 1);
  710. % hold on
  711. % plot(freqvals(freqvalindicesunder5Hz), GrandAverageSurrogatePLV_avacrosschans(freqvalindicesunder5Hz),'b');
  712. % hold on
  713. % shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAverageSurrogatePLV_avacrosschans(freqvalindicesunder5Hz), SE_SurrogatePLV(freqvalindicesunder5Hz), {'Color', 'b' }, 1);
  714. % hold on
  715. % xline(1.111, '--')
  716. % hold on
  717. % xline(2.222, '--')
  718. % hold on
  719. % xline(3.333, '--')
  720. % legend('structured', 'SE', 'surrogate', 'SE')
  721. % pdfname = ['ITC True data versus Surrogate data, All Channels, n = ' num2str(NSubjects)];
  722. % %pdfname = ['ITC FFT Auditory ROI'];
  723. % print('-dpdf', pdfname); %save as postscript in order to merge two files
  724. % z score plot as sanity check
  725. %truncated
  726. %freqvalindicesunder5Hz = find(freqvals <= 5);
  727. figure; plot(freqvals(freqvalindicesunder5Hz), GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz),'r');
  728. hold on
  729. %shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), 'lineprops','r') %old syntax for shadedErrorBar
  730. shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz), SE_ZScoreTruePLV(freqvalindicesunder5Hz), {'Color', 'r' }, 1);
  731. hold on
  732. xline(1.111, '--')
  733. hold on
  734. xline(2.222, '--')
  735. hold on
  736. xline(3.333, '--')
  737. yline(0, 'k-', 'LineWidth', 1)
  738. ylabel('ZITC')
  739. xlabel('Frequency (Hz)')
  740. legend('ZITC', 'SE')
  741. pdfname = ['Z scored ITC, All Channels, n = ' num2str(NSubjects)];
  742. print('-dpdf', pdfname); %save as postscript in order to merge two files
  743. % plot topographical distribution of z scores
  744. WordFreqScaleLimits = [-1 1]; %[-0.15 .15]; %so that 0 is centered on green.
  745. SyllableFreqScaleLimits = [-8 8];
  746. DifferenceEffectScaleLimits = [-0.05 0.05];
  747. figure;
  748. subplot(1,2,1)
  749. topoplot(GrandAverageZscore(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  750. title('ZITC, Word Frequency');
  751. subplot(1,2,2)
  752. topoplot(GrandAverageZscore(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  753. title('ZITC, Syllable Frequency');
  754. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'landscape', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  755. filename = ['ZITC Topographical Distributions, n = ' num2str(NSubjects)];
  756. print ('-dtiff', filename);
  757. print ('-dpdf', filename);
  758. %plot significaint electrodes that show significant entrainment at each frequency,
  759. %use a one-sample t-test against 0
  760. WordZITCByElectrodesandBySubject = zscoreTruePLVMtx(SubjectList, :, WordFreq);
  761. SyllableZITCByElectrodesandBySubject = zscoreTruePLVMtx(SubjectList, :, SyllableFreq);
  762. [SigWordElectrodesArray, PWord] = ttest(WordZITCByElectrodesandBySubject, 0, 'tail', 'right'); %one directional t-test, mean is greater than 0
  763. [SigSyllableElectrodesArray, PSyllable] = ttest(SyllableZITCByElectrodesandBySubject, 0, 'tail', 'right'); %one directional t-test, mean is greater than 0
  764. SigWordElectrodes = find(SigWordElectrodesArray ==1);
  765. SigSyllableElectrodes = find(SigSyllableElectrodesArray ==1);
  766. NumSigWordElectrodes = numel(SigWordElectrodes);
  767. NumSigSyllableElectrodes = numel(SigSyllableElectrodes);
  768. figure;
  769. subplot(1,2,1)
  770. topoplot(GrandAverageZscore(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits,'shading','interp', 'emarker2', {SigWordElectrodes ,'p','k', 7, 1} ); colorbar;
  771. title(['Significant Word ITC Electrodes: ' num2str(NumSigWordElectrodes)]);
  772. subplot(1,2,2)
  773. topoplot(GrandAverageZscore(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits,'shading','interp', 'emarker2', {SigSyllableElectrodes ,'p','k', 7, 1} ); colorbar;
  774. title(['Significant Syllable ITC Electrodes: ' num2str(NumSigSyllableElectrodes)]);
  775. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  776. filename = ['ZITC Topo, Sig Electrodes, n = ' num2str(NSubjects)];
  777. print ('-dtiff', filename);
  778. % extract individual level variables for statistical analysis
  779. ZScoreITCWordFreqMtx = zscoreTruePLVMtx(SubjectList,:, WordFreq); %nsubj X nchan
  780. ZScoreITCSyllableFreqMtx = zscoreTruePLVMtx(SubjectList,:, SyllableFreq);
  781. %ZScoreWLI = (ZScoreITCWordFreqMtx ./ ZScoreITCSyllableFreqMtx); %no longer sure whether the WLI is that informative considering we are now already normalizing by the surrogate shuffled data for each participant and electrode
  782. %variables based on channel configurations
  783. allchans= 1:104;
  784. ZScoreITCWordFreqMtx_allchans = mean(ZScoreITCWordFreqMtx(:,allchans),2);
  785. ZScoreITCSyllableFreqMtx_allchans = mean(ZScoreITCSyllableFreqMtx(:,allchans),2);
  786. %ZScoreWLI_allchans = mean(ZScoreWLI(:,allchans),2);
  787. SPSSToCompare = [ZScoreITCWordFreqMtx_allchans, ZScoreITCSyllableFreqMtx_allchans];
  788. CorrespondingSubjectIDs = SubjectIDList;
  789. %can build the array one group at a time
  790. %% GROUP COMPARISONS - COMPARING TWO GROUPS AT TIME - ZITC GRAND AVERAGE
  791. Group1Name = TDC;
  792. Group2Name = FXS;
  793. % -- GROUP 1 ---
  794. Group1SubjectList = [];
  795. %get subject list
  796. for x = 1:length(FFTfile_names)
  797. SubjectNumber = cell2mat(extractBetween(FFTfile_names{x}, 1, 4));
  798. if ismember(SubjectNumber, Group1Name)
  799. Group1SubjectList = [Group1SubjectList, x];
  800. end
  801. end
  802. % -- GROUP 2 ---
  803. Group2SubjectList = [];
  804. %get subject list
  805. for x = 1:length(FFTfile_names)
  806. SubjectNumber = cell2mat(extractBetween(FFTfile_names{x}, 1, 4));
  807. if ismember(SubjectNumber, Group2Name)
  808. Group2SubjectList = [Group2SubjectList, x];
  809. end
  810. end
  811. % -- GROUP 1 --
  812. clear PLVMtx Struct* Rand* Grand* PLV*
  813. Group1TruePLVMtx = [];
  814. Group1SurrogatePLVMtx = [];
  815. Group1zscoreTruePLVMtx = [];
  816. for i = Group1SubjectList
  817. clear EEGfrq* SurrogateDataFileName SurrogateDatasetsMtx zscoreTruePLV
  818. display(i)
  819. %load "true" data
  820. cd(FFTfile_location)
  821. load(FFTfile_names{i})
  822. disp(FFTfile_names{i})
  823. PLVTrue = EEGfrq.plv(plotchan,:); %only extracts relevant channels
  824. Group1TruePLVMtx(i,:,:) = PLVTrue; %rows without corresponding subjects (e.g., 20) just contains 0s. This is taken into account below by selecting SubjectsToInclude as a dimension.
  825. %load corresponding surrogate data
  826. cd(FFTsurrogatefile_location)
  827. SurrogateDataFileName = [char(extractBetween(FFTfile_names{i}, 1,4)) '_EEGfreq_ByIteration.mat'];
  828. load(SurrogateDataFileName)
  829. for iterationnum = 1:size(EEGfrq_ByIteration.iteration,2)
  830. SurrogateDatasetsMtx(iterationnum,:,:) = EEGfrq_ByIteration.iteration(iterationnum).plv(plotchan,:); %nchan x nfreqs for each surrogate dataset; ndataset x nchan x nfreq
  831. end
  832. % Z score the data according to the surrogate distribution
  833. % each subject serves as their own Z score distribution
  834. Mean_Surrogate = squeeze(mean(SurrogateDatasetsMtx,1)); %average across the 100 surrogate datasets for the subject
  835. STD_Surrogate = squeeze(std(SurrogateDatasetsMtx)); %std deviation
  836. %compute z score
  837. zscoreTruePLV = (PLVTrue - Mean_Surrogate) ./ STD_Surrogate;
  838. Group1SurrogatePLVMtx(i,:,:) = Mean_Surrogate; %stores the mean surrogate ITCs for each subject; nregion x nfreqs
  839. Group1zscoreTruePLVMtx(i,:,:) = zscoreTruePLV; %stores the z scored actual observed data for each subject, nregion x nfreqs
  840. end
  841. % -- GROUP 2 --
  842. clear PLVMtx Struct* Rand* Grand* PLV*
  843. Group2TruePLVMtx = [];
  844. Group2SurrogatePLVMtx = [];
  845. Group2zscoreTruePLVMtx = [];
  846. for i = Group2SubjectList
  847. clear EEGfrq* SurrogateDataFileName SurrogateDatasetsMtx zscoreTruePLV
  848. display(i)
  849. %load "true" data
  850. cd(FFTfile_location)
  851. load(FFTfile_names{i})
  852. disp(FFTfile_names{i})
  853. PLVTrue = EEGfrq.plv(plotchan,:); %only extracts relevant channels
  854. Group2TruePLVMtx(i,:,:) = PLVTrue; %rows without corresponding subjects (e.g., 20) just contains 0s. This is taken into account below by selecting SubjectsToInclude as a dimension.
  855. %load corresponding surrogate data
  856. cd(FFTsurrogatefile_location)
  857. SurrogateDataFileName = [char(extractBetween(FFTfile_names{i}, 1,4)) '_EEGfreq_ByIteration.mat'];
  858. load(SurrogateDataFileName)
  859. for iterationnum = 1:size(EEGfrq_ByIteration.iteration,2)
  860. SurrogateDatasetsMtx(iterationnum,:,:) = EEGfrq_ByIteration.iteration(iterationnum).plv(plotchan,:); %nchan x nfreqs for each surrogate dataset; ndataset x nchan x nfreq
  861. end
  862. % Z score the data according to the surrogate distribution
  863. % each subject serves as their own Z score distribution
  864. Mean_Surrogate = squeeze(mean(SurrogateDatasetsMtx,1)); %average across the 100 surrogate datasets for the subject
  865. STD_Surrogate = squeeze(std(SurrogateDatasetsMtx)); %std deviation
  866. %compute z score
  867. zscoreTruePLV = (PLVTrue - Mean_Surrogate) ./ STD_Surrogate;
  868. Group2SurrogatePLVMtx(i,:,:) = Mean_Surrogate; %stores the mean surrogate ITCs for each subject; nregion x nfreqs
  869. Group2zscoreTruePLVMtx(i,:,:) = zscoreTruePLV; %stores the z scored actual observed data for each subject, nregion x nfreqs
  870. end
  871. % -- to extract individual level variables --
  872. freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  873. [~, WordFreq] = min(abs(freqvals-1.1111));
  874. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  875. % - Group 1 -
  876. Group1GrandAverageTruePLV = squeeze(mean(Group1TruePLVMtx(Group1SubjectList,:,:),1));
  877. Group1GrandAverageTruePLV_avacrosschans = mean(Group1GrandAverageTruePLV(:,:),1);
  878. Group1GrandAverageSurrogatePLV = squeeze(mean(Group1SurrogatePLVMtx(Group1SubjectList,:,:),1));
  879. Group1GrandAverageSurrogatePLV_avacrosschans = mean(Group1GrandAverageSurrogatePLV(:,:),1);
  880. %Standard Error
  881. Group1TruePLV_averageacrosschans = squeeze(mean(Group1TruePLVMtx(Group1SubjectList,:,:),2)); %now nsubj x nfreq
  882. Group1STD_TruePLV = std(Group1TruePLV_averageacrosschans(:,:)); %nfreqs
  883. Group1SE_TruePLV = Group1STD_TruePLV /sqrt(numel(Group1SubjectList));
  884. Group1SurrogatePLV_averageacrosschans = squeeze(mean(Group1SurrogatePLVMtx(Group1SubjectList,:,:),2)); %now nsubj x nfreq
  885. Group1STD_SurrogatePLV = std(Group1SurrogatePLV_averageacrosschans(:,:)); %nfreqs
  886. Group1SE_SurrogatePLV = Group1STD_SurrogatePLV /sqrt(numel(Group1SubjectList));
  887. %Z scores
  888. Group1GrandAverageZscore = squeeze(mean(Group1zscoreTruePLVMtx(Group1SubjectList,:,:),1));
  889. Group1GrandAverageZscore_avacrosselectrodes = mean(Group1GrandAverageZscore,1);
  890. %standard error
  891. Group1ZScoreTruePLV_averageacrosschans = squeeze(mean(Group1zscoreTruePLVMtx(Group1SubjectList,:,:),2)); %now nsubj x nfreq
  892. Group1STD_ZScoreTruePLV = std(Group1ZScoreTruePLV_averageacrosschans(:,:)); %nfreqs
  893. Group1SE_ZScoreTruePLV = Group1STD_ZScoreTruePLV /sqrt(numel(Group1SubjectList));
  894. % - Group 2 -
  895. Group2GrandAverageTruePLV = squeeze(mean(Group2TruePLVMtx(Group2SubjectList,:,:),1));
  896. Group2GrandAverageTruePLV_avacrosschans = mean(Group2GrandAverageTruePLV(:,:),1);
  897. Group2GrandAverageSurrogatePLV = squeeze(mean(Group2SurrogatePLVMtx(Group2SubjectList,:,:),1));
  898. Group2GrandAverageSurrogatePLV_avacrosschans = mean(Group2GrandAverageSurrogatePLV(:,:),1);
  899. %Standard Error
  900. Group2TruePLV_averageacrosschans = squeeze(mean(Group2TruePLVMtx(Group2SubjectList,:,:),2)); %now nsubj x nfreq
  901. Group2STD_TruePLV = std(Group2TruePLV_averageacrosschans(:,:)); %nfreqs
  902. Group2SE_TruePLV = Group2STD_TruePLV /sqrt(numel(Group2SubjectList));
  903. Group2SurrogatePLV_averageacrosschans = squeeze(mean(Group2SurrogatePLVMtx(Group2SubjectList,:,:),2)); %now nsubj x nfreq
  904. Group2STD_SurrogatePLV = std(Group2SurrogatePLV_averageacrosschans(:,:)); %nfreqs
  905. Group2SE_SurrogatePLV = Group2STD_SurrogatePLV /sqrt(numel(Group2SubjectList));
  906. %Z scores
  907. Group2GrandAverageZscore = squeeze(mean(Group2zscoreTruePLVMtx(Group2SubjectList,:,:),1));
  908. Group2GrandAverageZscore_avacrosselectrodes = mean(Group2GrandAverageZscore,1);
  909. %standard error
  910. Group2ZScoreTruePLV_averageacrosschans = squeeze(mean(Group2zscoreTruePLVMtx(Group2SubjectList,:,:),2)); %now nsubj x nfreq
  911. Group2STD_ZScoreTruePLV = std(Group2ZScoreTruePLV_averageacrosschans(:,:)); %nfreqs
  912. Group2SE_ZScoreTruePLV = Group2STD_ZScoreTruePLV /sqrt(numel(Group2SubjectList));
  913. NSubjectsGroup1 = numel(Group1SubjectList);
  914. NSubjectsGroup2 = numel(Group2SubjectList);
  915. %---- Plots ------
  916. cd([CurrentDirectory 'FXS Project/infant pipeline/grand averages/z scored grand averages/'])
  917. %truncated
  918. %freqvalindicesunder5Hz = find(freqvals <= 5);
  919. freqvalindicesunder5Hz = find(freqvals <= 4);
  920. %z score plot
  921. figure; h1 = plot(freqvals(freqvalindicesunder5Hz), Group1GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz),'k', 'LineWidth', 2);
  922. hold on
  923. %shadedErrorBar(freqvals(freqvalindicesunder5Hz),GrandAveragePLV_avacrosschans_Structured(freqvalindicesunder5Hz), SE_Structured(freqvalindicesunder5Hz), 'lineprops','r') %old syntax for shadedErrorBar
  924. h = shadedErrorBar(freqvals(freqvalindicesunder5Hz),Group1GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz), Group1SE_ZScoreTruePLV(freqvalindicesunder5Hz), {'Color', 'k' }, 1);
  925. hold on
  926. h2 = plot(freqvals(freqvalindicesunder5Hz), Group2GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz),'r', 'LineWidth', 2);
  927. hold on
  928. h = shadedErrorBar(freqvals(freqvalindicesunder5Hz),Group2GrandAverageZscore_avacrosselectrodes(freqvalindicesunder5Hz), Group2SE_ZScoreTruePLV(freqvalindicesunder5Hz), {'Color', 'r' }, 1);
  929. hold on
  930. xline(1.111, '--')
  931. hold on
  932. xline(2.222, '--')
  933. hold on
  934. xline(3.333, '--')
  935. yline(0, 'k-', 'LineWidth', 1)
  936. ylabel('ZITC')
  937. xlabel('Frequency (Hz)')
  938. %legend([h1, h2], {'TDC', 'FXS'})
  939. set(gca, 'FontSize', 14);
  940. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'portrait', 'PaperPosition', [0.5 0.5 8.0 10.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  941. figurename = ['Z scored ITC, Two Group Comparison, All Channels, No Legend, nGroup1 = ' num2str(NSubjectsGroup1), ' nGroup2 = ' num2str(NSubjectsGroup2) ];
  942. exportgraphics(gcf, [figurename '.pdf'], 'ContentType','vector'); %this should import as a vector now
  943. %print('-dpdf', figurename); %save as postscript in order to merge two files
  944. %print('-dtiff', figurename); %save as postscript in order to merge two files
  945. % plot topographical distribution of z scores
  946. WordFreqScaleLimits = [-1 1]; %[-0.15 .15]; %so that 0 is centered on green.
  947. SyllableFreqScaleLimits = [-8 8];
  948. DifferenceEffectScaleLimits = [-0.05 0.05];
  949. figure;
  950. subplot(2,2,1)
  951. topoplot(Group1GrandAverageZscore(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  952. %title('TDC Word Frequency');
  953. subplot(2,2,2)
  954. topoplot(Group1GrandAverageZscore(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  955. %title('TDC Syllable Frequency');
  956. subplot(2,2,3)
  957. topoplot(Group2GrandAverageZscore(:,WordFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', WordFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  958. %title('FXS Word Frequency');
  959. subplot(2,2,4)
  960. topoplot(Group2GrandAverageZscore(:,SyllableFreq), locsfile, 'style', 'map', 'colormap', jet, 'maplimits', SyllableFreqScaleLimits, 'plotrad',.5,'headrad',.5,'shading','interp'); colorbar;
  961. %title('FXS Syllable Frequency');
  962. set(gcf,'PaperPositionMode','manual', 'PaperOrientation', 'landscape', 'PaperPosition', [0.05 0.15 12.0 8.50]) %corresponds to settings on Print Preview. %good measurements for not cutting off title.
  963. filename = ['ZITC Group Comparison Topographical Distributions, no titles, nGroup1 = ' num2str(NSubjectsGroup1), ' nGroup2 = ' num2str(NSubjectsGroup2)];
  964. exportgraphics(gcf, filename + ".pdf", 'ContentType','vector');
  965. %print ('-dtiff', filename);
  966. %print ('-dpdf', filename);
  967. %% JACKKNIFE PROCEDURE TO ESTIMATE ITPC RELIABILITY
  968. %load the same FFT parameters as above. (LOAD PARAMETERS cell)
  969. ParticipantLevelData = [];
  970. PseudovalsByParticipantByEpoch = []; %timecourse data
  971. subjectcounter = 0;
  972. for subji = AllSubjectIndices %length(datafile_names)
  973. SubjectName = datafile_names{subji}(1:4); %string
  974. SubjectNumber = str2double(SubjectName); %number
  975. disp(subji)
  976. disp(SubjectName)
  977. subjectcounter = subjectcounter + 1;
  978. %figure out GroupID
  979. clear GroupID
  980. if any(strcmp(SubjectName, TDC))
  981. GroupID = 1;
  982. elseif any(strcmp(SubjectName, FXS))
  983. GroupID = 2;
  984. elseif any(strcmp(SubjectName, ASD))
  985. GroupID = 3;
  986. else
  987. GroupID = 0; %unclassified, but at least it won't disrupt the loop
  988. end
  989. %load dataset
  990. clear EEGfrq
  991. STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[];
  992. EEG = pop_loadset( 'filename', [SubjectName '_epoched.set'], 'filepath', [CurrentDirectory 'FXS project/infant pipeline/epochs/']);
  993. [ALLEEG, EEG, CURRENTSET] = eeg_store( ALLEEG, EEG );
  994. ParentEEG = EEG;
  995. NumTrials = EEG.trials;
  996. FullTrialArray = 1:NumTrials;
  997. NumberofChannels = size(EEG.chanlocs,2);
  998. % ------
  999. %create temporarily subdivided datasets and run the function on each dataset
  1000. %first create the big frq structure
  1001. EEGfrq = frqa_plvpwr(EEG, 'foutput',foutput,'fband',fband,'binsSNR',binsSNR,...
  1002. 'typeSNRPWR',typeSNRPWR,'typeSNRPLV',typeSNRPLV,...
  1003. 'zscorePWR',zscorePWR,'zscorePLV',zscorePLV);
  1004. freqvals = EEGfrq.freqs; %freqs based on last subject loaded
  1005. [~, WordFreq] = min(abs(freqvals-1.1111));
  1006. [~, SyllableFreq] = min(abs(freqvals-3.3333)); %syllable freq = 3.33 Hz
  1007. %for normalization, extract neighbouring bins excluding the word,
  1008. %harmonics, and syllable frequencies.
  1009. [~, Harmonic1Freq] = min(abs(freqvals-2.22222)); %syllable freq = 3.33 Hz
  1010. [~, Harmonic2Freq] = min(abs(freqvals-4.44444)); %syllable freq = 3.33 Hz
  1011. NormalizationFreqBins = setdiff(find(freqvals <= 5), [WordFreq, SyllableFreq, Harmonic1Freq, Harmonic2Freq]);
  1012. %compute ITC
  1013. AllTrialsWordITC = EEGfrq.plv(:,WordFreq);
  1014. AllTrialsSyllableITC = EEGfrq.plv(:,SyllableFreq);
  1015. AllTrialsNormalizedBinsITC = squeeze(mean(EEGfrq.plv(:, NormalizationFreqBins ),2));
  1016. AllTrialsWordITCNormalized = AllTrialsWordITC - AllTrialsNormalizedBinsITC;
  1017. AllTrialsSyllableITCNormalized = AllTrialsSyllableITC - AllTrialsNormalizedBinsITC;
  1018. EEGfrq_jackknifed.replication(1:NumTrials) = EEGfrq; %preallocate - delete extra rows later - in order to have a bigger structure with the same structure
  1019. WordITCJackknifed_ByReplication= [];
  1020. SyllableITCJackknifed_ByReplication = [];
  1021. WordITCNormalizedJackknifed_ByReplication = [];
  1022. SyllableITCNormalizedJackknifed_ByReplication = [];
  1023. for replication = 1:NumTrials
  1024. disp(['Replication Number :' num2str(replication)])
  1025. %compute what ITC would be without that trial
  1026. TrialArrayLessOneTrial = setdiff(FullTrialArray, replication); %removes N trial
  1027. EEGLessOneTrial = pop_select( ParentEEG, 'trial', TrialArrayLessOneTrial);
  1028. %run command on subsampled trials
  1029. EEGfrqLessOneTrial = frqa_plvpwr(EEGLessOneTrial, 'foutput',foutput,'fband',fband,'binsSNR',binsSNR,...
  1030. 'typeSNRPWR',typeSNRPWR,'typeSNRPLV',typeSNRPLV,...
  1031. 'zscorePWR',zscorePWR,'zscorePLV',zscorePLV);
  1032. EEGfrq_jackknifed.replication(replication) = EEGfrqLessOneTrial;
  1033. %compute individual actual and normalized ITC values to store for analysis
  1034. WordITCJackknifed = EEGfrqLessOneTrial.plv(:,WordFreq);
  1035. SyllableITCJackknifed = EEGfrqLessOneTrial.plv(:,SyllableFreq);
  1036. OtherFreqsITCJackknifed = squeeze(mean(EEGfrqLessOneTrial.plv(:, NormalizationFreqBins ),2));
  1037. WordITCNormalizedJackknifed = WordITCJackknifed - OtherFreqsITCJackknifed;
  1038. SyllableITCNormalizedJackknifed = SyllableITCJackknifed - OtherFreqsITCJackknifed;
  1039. %store
  1040. WordITCJackknifed_ByReplication(replication,:) = WordITCJackknifed; %Nreplications x NElectrodes
  1041. SyllableITCJackknifed_ByReplication(replication,:) = SyllableITCJackknifed; %Nreplications x NElectrodes
  1042. WordITCNormalizedJackknifed_ByReplication(replication,:) = WordITCNormalizedJackknifed; %Nreplications x NElectrodes
  1043. SyllableITCNormalizedJackknifed_ByReplication(replication,:) = SyllableITCNormalizedJackknifed; %Nreplications x NElectrodes
  1044. clear EEGfrqLessOneTrial
  1045. end
  1046. %save the participant's EEG freq matrix
  1047. cd([CurrentDirectory 'FXS Project/infant pipeline/jackknifed FFT files/'])
  1048. disp(SubjectNumber)
  1049. %filename = strcat(num2str(SubjectNumber), '_EEGfrq_jackknifed');
  1050. filename = [SubjectName '_EEGfrq_jackknifed'];
  1051. save(filename, 'EEGfrq_jackknifed');
  1052. %average steps to save in participant matrix
  1053. %average across channels
  1054. WordITCJackknifed_ByReplication_meanacrosschans = mean(WordITCJackknifed_ByReplication,2);
  1055. SyllableITCJackknifed_ByReplication_meanacrosschans = mean(SyllableITCJackknifed_ByReplication,2);
  1056. WordITCNormalizedJackknifed_ByReplication_meanacrosschans = mean(WordITCNormalizedJackknifed_ByReplication,2);
  1057. SyllableITCNormalizedJackknifed_ByReplication_meanacrosschans = mean(SyllableITCNormalizedJackknifed_ByReplication,2);
  1058. %average across replications
  1059. MeanWordITCJackknifed_ByReplication_meanacrosschans = mean(WordITCJackknifed_ByReplication_meanacrosschans);
  1060. MeanSyllableITCJackknifed_ByReplication_meanacrosschans = mean(SyllableITCJackknifed_ByReplication_meanacrosschans);
  1061. MeanWordITCNormJackknifed_ByReplication_meanacrosschans = mean( WordITCNormalizedJackknifed_ByReplication_meanacrosschans);
  1062. MeanSyllableITCNormJackknifed_ByReplication_meanacrosschans = mean(SyllableITCNormalizedJackknifed_ByReplication_meanacrosschans);
  1063. %original ITC values as computed across all trials (from above), average across channels
  1064. AllTrialsWordITC_meanacrosschans = mean(AllTrialsWordITC,1);
  1065. AllTrialsSyllableITC_meanacrosschans = mean(AllTrialsSyllableITC,1);
  1066. AllTrialsWordITCNormalized_meanacrosschans = mean(AllTrialsWordITCNormalized,1);
  1067. AllTrialsSyllableITCNormalized_meanacrosschans = mean(AllTrialsSyllableITCNormalized,1);
  1068. %jackknife pseudovals - a pseudo-value is calculated as the difference
  1069. %between the whole sample estimate and the partial estimate. This tells
  1070. %you whether each individual trial contributes to lowering or increasing the ITC and by how much. Perfectly inversely correlated with jackknifed
  1071. %ITC values (rest of the sample ITC). So a higher pseudoval would
  1072. %indicate that the contribution of that specific trial INCREASES the
  1073. %overall ITC (such that when that trial is removed, the remaining trial
  1074. %ITC is lower). Formula from https://www.mattcraddock.com/blog/2020/09/07/jackknife-intertrial-coherence-and-phase/
  1075. WordITCPseudovals_ByReplication_meanacrosschans = NumTrials*AllTrialsWordITC_meanacrosschans - ((NumTrials-1) *WordITCJackknifed_ByReplication_meanacrosschans); %Ntrial
  1076. SyllableITCPseudovals_ByReplication_meanacrosschans = NumTrials*AllTrialsSyllableITC_meanacrosschans - ((NumTrials-1) *SyllableITCJackknifed_ByReplication_meanacrosschans);
  1077. WordITCNormalizedPseudovals_ByReplication_meanacrosschans = NumTrials*AllTrialsWordITCNormalized_meanacrosschans - ((NumTrials-1) *WordITCNormalizedJackknifed_ByReplication_meanacrosschans); %Ntrial
  1078. SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans = NumTrials*AllTrialsSyllableITCNormalized_meanacrosschans - ((NumTrials-1) *SyllableITCNormalizedJackknifed_ByReplication_meanacrosschans);
  1079. %exact values to store in participant level matrices
  1080. %mean of pseudovalues can be viewed as a bias reduced version of the original statistic
  1081. MeanWordITCPseudovals_ByReplication_meanacrosschans = mean(WordITCPseudovals_ByReplication_meanacrosschans);
  1082. MeanSyllableITCPseudovals_ByReplication_meanacrosschans = mean(SyllableITCPseudovals_ByReplication_meanacrosschans);
  1083. MeanWordITCNormalPseudovals_ByReplication_meanacrosschans = mean(WordITCNormalizedPseudovals_ByReplication_meanacrosschans);
  1084. MeanSyllableITCNormalPseudovals_ByReplication_meanacrosschans = mean(SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans);
  1085. %standard deviation of pseudovalues
  1086. StDevWordITCPseudovals_ByReplication_meanacrosschans = std(WordITCPseudovals_ByReplication_meanacrosschans);
  1087. StDevSyllableITPseudovals_ByReplication_meanacrosschans = std(SyllableITCPseudovals_ByReplication_meanacrosschans);
  1088. StDevWordITCNormalPseudovals_ByReplication_meanacrosschans = std(WordITCNormalizedPseudovals_ByReplication_meanacrosschans);
  1089. StDevSyllableITCNormalPseudovals_ByReplication_meanacrosschans = std(SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans);
  1090. %take the highest 5 and 10 pseudovalues:
  1091. %5
  1092. Max5WordITCPseudovals_ByReplication_meanacrosschans = mean(maxk(WordITCPseudovals_ByReplication_meanacrosschans, 5));
  1093. Max5SyllableITPseudovals_ByReplication_meanacrosschans = mean(maxk(SyllableITCPseudovals_ByReplication_meanacrosschans, 5));
  1094. Max5WordITCNormalPseudovals_ByReplication_meanacrosschans = mean(maxk(WordITCNormalizedPseudovals_ByReplication_meanacrosschans, 5));
  1095. Max5SyllableITCNormalPseudovals_ByReplication_meanacrosschans = mean(maxk(SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans, 5));
  1096. %10th
  1097. Max10WordITCPseudovals_ByReplication_meanacrosschans = mean(maxk(WordITCPseudovals_ByReplication_meanacrosschans, 10));
  1098. Max10SyllableITPseudovals_ByReplication_meanacrosschans = mean(maxk(SyllableITCPseudovals_ByReplication_meanacrosschans, 10));
  1099. Max10WordITCNormalPseudovals_ByReplication_meanacrosschans = mean(maxk(WordITCNormalizedPseudovals_ByReplication_meanacrosschans, 10));
  1100. Max10SyllableITCNormalPseudovals_ByReplication_meanacrosschans = mean(maxk(SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans, 10));
  1101. %Trial indices associated with >0 Positive Pseudovalues
  1102. %positive pseudovalues means that the trial was contributing positively to the overall
  1103. %ITC estimate; in other words, when that trial is removed, ITC across
  1104. %the remaining trials DECREASES.
  1105. %A negative pseudovalue means that the trial was disrupting or reducing
  1106. %phase coherence potentially due to noise, phase jitter, or phase-locking at a different angle. In other words, removing that trial INCREASES ITPC
  1107. %this could give insight to the temporal trajecotry of participants' learning.
  1108. PositiveContributingTrialsToWordITC= find(WordITCPseudovals_ByReplication_meanacrosschans >0);
  1109. PositiveContributingTrialsToSyllableITC = find(SyllableITCPseudovals_ByReplication_meanacrosschans >0);
  1110. PositiveContributingTrialsToWordITCNormalized= find(WordITCNormalizedPseudovals_ByReplication_meanacrosschans >0);
  1111. PositiveContributingTrialsToSyllableITCNormalized= find(SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans >0);
  1112. %summarize the total number of positive contributing trials - perhaps
  1113. %this is a proxy of participants' overall time spent parsing or
  1114. %processing the word structures
  1115. NumberPositiveContributingTrialsToWordITC = numel(PositiveContributingTrialsToWordITC);
  1116. NumberPositiveContributingTrialsToSyllableITC = numel(PositiveContributingTrialsToSyllableITC);
  1117. NumberPositiveContributingTrialsToWordITCNormalized = numel(PositiveContributingTrialsToWordITCNormalized);
  1118. NumberPositiveContributingTrialsToSyllableITCNormalized = numel(PositiveContributingTrialsToSyllableITCNormalized);
  1119. ParticipantLevelData(subjectcounter,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:) = [SubjectNumber, GroupID, AllTrialsWordITC_meanacrosschans, AllTrialsSyllableITC_meanacrosschans, ...
  1120. AllTrialsWordITCNormalized_meanacrosschans, AllTrialsSyllableITCNormalized_meanacrosschans, MeanWordITCPseudovals_ByReplication_meanacrosschans, MeanSyllableITCPseudovals_ByReplication_meanacrosschans , ...
  1121. MeanWordITCNormalPseudovals_ByReplication_meanacrosschans, MeanSyllableITCNormalPseudovals_ByReplication_meanacrosschans, ...
  1122. Max5WordITCPseudovals_ByReplication_meanacrosschans, Max5SyllableITPseudovals_ByReplication_meanacrosschans, ...
  1123. Max5WordITCNormalPseudovals_ByReplication_meanacrosschans, Max5SyllableITCNormalPseudovals_ByReplication_meanacrosschans, Max10WordITCPseudovals_ByReplication_meanacrosschans, Max10SyllableITPseudovals_ByReplication_meanacrosschans, ...
  1124. Max10WordITCNormalPseudovals_ByReplication_meanacrosschans, Max10SyllableITCNormalPseudovals_ByReplication_meanacrosschans, ...
  1125. NumberPositiveContributingTrialsToWordITC, NumberPositiveContributingTrialsToSyllableITC, NumberPositiveContributingTrialsToWordITCNormalized, ...
  1126. NumberPositiveContributingTrialsToSyllableITCNormalized];
  1127. %now we will save the pseudovals to enable time course analysis:
  1128. TrialArrayToUse = [1:NumTrials]';
  1129. PseudovalArrays = [WordITCPseudovals_ByReplication_meanacrosschans, SyllableITCPseudovals_ByReplication_meanacrosschans, ...
  1130. WordITCNormalizedPseudovals_ByReplication_meanacrosschans, SyllableITCNormalizedPseudovals_ByReplication_meanacrosschans];
  1131. SubjectIDRepArray = repmat(SubjectNumber, size(TrialArrayToUse));
  1132. GroupIDRepArray = repmat(GroupID, size(TrialArrayToUse));
  1133. CurrentSubjectData = [SubjectIDRepArray, GroupIDRepArray, TrialArrayToUse, PseudovalArrays];
  1134. PseudovalsByParticipantByEpoch = vertcat( PseudovalsByParticipantByEpoch , CurrentSubjectData);
  1135. end
  1136. cd([CurrentDirectory 'FXS Project/infant pipeline/jackknifed FFT files/summary tables']) %so that files go in proper place
  1137. %after all participants have run, create and save as a table
  1138. %save as table
  1139. ColumnNames = {'Subject', 'Group', 'AllTrialsWordITC', 'AllTrialsSyllableITC', 'AllTrialsWordITCNormalized', 'AllTrialsSyllableITCNormalized', ...
  1140. 'MeanWordITCPseudovals', 'MeanSyllableITCPseudovals', 'MeanWordITCNormalPseudovals_ByReplication_meanacrosschans', 'MeanSyllableITCNormalPseudovals_ByReplication_meanacrosschans', ...
  1141. 'Max5WordITCPseudovals', 'Max5SyllableITPseudovals', 'Max5WordITCNormPseudovals', 'Max5SyllableITCNormPseudovals', 'Max10WordITCPseudovals', 'Max10SyllableITPseudovals', ...
  1142. 'Max10WordITCNormalPseudovals', 'Max10SyllableITCNormalPseudovals', 'NumberPosContributingTrialsToWordITC', 'NumberPosContributingTrialsToSyllableITC', ...
  1143. 'NumberPosContributingTrialsToWordITCNorm' 'NumberPosContributingTrialsToSyllableITCNorm'};
  1144. ParticipantDataTableForAnalysis = array2table(ParticipantLevelData(1:end,:), 'VariableNames', ColumnNames);
  1145. writetable(ParticipantDataTableForAnalysis,'ParticipantDataTableForAnalysis.csv')
  1146. %Table 2 - timecourse data
  1147. ColumnNames2 = {'Subject', 'Group', 'EpochNum', 'WordITCPseudoval', 'SyllableITCPseudoval', 'WordITCNormPseudoval', 'SyllableITCNormPseudoval'};
  1148. PseudovalTimecourseTableForAnalysis = array2table(PseudovalsByParticipantByEpoch, 'VariableNames', ColumnNames2);
  1149. writetable(PseudovalTimecourseTableForAnalysis,'PseudovalTimecourseTableForAnalysis.csv')

MainITCScript.m, under CC-BY-4.0 · at the source

Overview

Authors: Laura J Batterink1, Yanchen Liu2, Grace Westerkamp2, Jae Citarella2, Peyton Siekierski2,3, Lynxie Voorhees2, Lauren E Ethridge4,5, Elizabeth Smith6, Rana Elmaghraby2,3, Craig A Erickson2,3, Zag ElSayed7, Anubhuti Goel8,9, Steve W Wu10,11, Ernest V Pedapati2,3,10,11
  1. Department of Psychology; Western Centre for Brain and Mind, Western Institute for Neuroscience, University of Western Ontario, London, Ontario, Canada
  2. Division of Child and Adolescent Psychiatry, Cincinnati Children's Hospital Medical Center, Cincinnati, Ohio, USA
  3. Department of Psychiatry, University of Cincinnati College of Medicine, Cincinnati, Ohio, USA
  4. Department of Pediatrics, Section on Developmental and Behavioral Pediatrics, University of Oklahoma Health Sciences Center, Oklahoma City, Oklahoma, USA
  5. Department of Psychology, University of Oklahoma, Norman, Oklahoma, USA
  6. Division of Behavioral Medicine and Clinical Psychology, Cincinnati Children's Hospital Medical Center, Cincinnati, Ohio, USA
  7. School of Information Technology, University of Cincinnati, Ohio, USA
  8. Neuroscience Graduate Program, University of California, Riverside, Riverside, California, USA
  9. Department of Psychology, University of California, Riverside, Riverside, California, USA
  10. Division of Neurology, Cincinnati Children's Hospital Medical Center, Cincinnati, Ohio, USA
  11. Department of Pediatrics, University of Cincinnati College of Medicine, Cincinnati, Ohio, USA
Dates: received 29 October 2025; accepted 3 July 2026; published online 12 July 2026; in print August 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1002/aur.70312 · PMID 42437723 · PMCID PMC13472007 · OpenAlex W4415071967
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: EEG (modality), human (organism), other condition (population), autism (population), cognitive (subfield)
Methods: Spectral & time-frequency, Preprocessing, Statistics, Connectivity, Smoothing, state filtering, decompositions, Physiology & signal measures
Keywords: auditory processing, EEG, electroencephalography, fragile X syndrome, language development, neural entrainment, statistical learning
MeSH: Fragile X Syndrome*, Learning Disabilities*, Speech*, Speech Perception*, Adolescent, Auditory Cortex, Child, Electroencephalography, Female, Humans, Language Development Disorders, Male, Temporal Lobe (* major topic)
Topic: Genetics and Neurodevelopmental Disorders (Genetics, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: Eunice Kennedy Shriver National Institute of Child Health and Human Development (5R01HD108222-03, 5R01HD108222‐03); NICHD NIH HHS (R01 HD108222)
Citations: not cited yet (Europe PMC); 105 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repository

Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.

Zenodo 18746668

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 3 files
Software Heritage: not checked
Found in: “Data Availability Statement”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Statistics and Machine Learning Toolbox (3 files), EEGLAB (1 file), ERPLAB (1 file), shadedErrorBar (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
5 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 5 scripts, each with its path and the digest of its content;
  • 5 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Code and data availability statement

The paper has a code and data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1002/aur.70312.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 2, 28 September 2026

  • Publisher: n/a → Wiley

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 14 authors, 7 keywords, 13 MeSH terms, 2 funders, 104 references.

Cite

This paper

Batterink, L. J., Liu, Y., Westerkamp, G., Citarella, J., Siekierski, P., Voorhees, L., Ethridge, L. E., Smith, E., Elmaghraby, R., Erickson, C. A., ElSayed, Z., Goel, A., Wu, S. W., & Pedapati, E. V. (2026). Aberrant Neural Entrainment to Word-Level Speech Patterns in Fragile X Syndrome: Evidence for a Statistical Learning Deficit. Autism research : official journal of the International Society for Autism Research, 19(8), e70312. https://doi.org/10.1002/aur.70312

BibTeX

@article{batterink2026aberrant,
author = {Batterink, Laura J and Liu, Yanchen and Westerkamp, Grace and Citarella, Jae and Siekierski, Peyton and Voorhees, Lynxie and Ethridge, Lauren E and Smith, Elizabeth and Elmaghraby, Rana and Erickson, Craig A and ElSayed, Zag and Goel, Anubhuti and Wu, Steve W and Pedapati, Ernest V},
title = {{Aberrant Neural Entrainment to Word-Level Speech Patterns in Fragile X Syndrome: Evidence for a Statistical Learning Deficit}},
journal = {Autism research : official journal of the International Society for Autism Research},
year = {2026},
month = jul,
volume = {19},
number = {8},
pages = {e70312},
publisher = {Wiley},
issn = {1939-3792},
doi = {10.1002/aur.70312},
url = {https://doi.org/10.1002/aur.70312},
pmid = {42437723},
pmcid = {PMC13472007}
}

RIS

TY - JOUR
AU - Batterink, Laura J
AU - Liu, Yanchen
AU - Westerkamp, Grace
AU - Citarella, Jae
AU - Siekierski, Peyton
AU - Voorhees, Lynxie
AU - Ethridge, Lauren E
AU - Smith, Elizabeth
AU - Elmaghraby, Rana
AU - Erickson, Craig A
AU - ElSayed, Zag
AU - Goel, Anubhuti
AU - Wu, Steve W
AU - Pedapati, Ernest V
TI - Aberrant Neural Entrainment to Word-Level Speech Patterns in Fragile X Syndrome: Evidence for a Statistical Learning Deficit
T2 - Autism research : official journal of the International Society for Autism Research
J2 - Autism Res
PY - 2026
DA - 2026/07/12
VL - 19
IS - 8
SP - e70312
SN - 1939-3792
PB - Wiley
DO - 10.1002/aur.70312
UR - https://doi.org/10.1002/aur.70312
LA - en
ER -

CSL-JSON

{
"id": "10.1002/aur.70312",
"type": "article-journal",
"title": "Aberrant Neural Entrainment to Word-Level Speech Patterns in Fragile X Syndrome: Evidence for a Statistical Learning Deficit",
"container-title": "Autism research : official journal of the International Society for Autism Research",
"author": [
{
"family": "Batterink",
"given": "Laura J"
},
{
"family": "Liu",
"given": "Yanchen"
},
{
"family": "Westerkamp",
"given": "Grace"
},
{
"family": "Citarella",
"given": "Jae"
},
{
"family": "Siekierski",
"given": "Peyton"
},
{
"family": "Voorhees",
"given": "Lynxie"
},
{
"family": "Ethridge",
"given": "Lauren E"
},
{
"family": "Smith",
"given": "Elizabeth"
},
{
"family": "Elmaghraby",
"given": "Rana"
},
{
"family": "Erickson",
"given": "Craig A"
},
{
"family": "ElSayed",
"given": "Zag"
},
{
"family": "Goel",
"given": "Anubhuti"
},
{
"family": "Wu",
"given": "Steve W"
},
{
"family": "Pedapati",
"given": "Ernest V"
}
],
"container-title-short": "Autism Res",
"volume": "19",
"issue": "8",
"page": "e70312",
"DOI": "10.1002/aur.70312",
"PMID": "42437723",
"PMCID": "PMC13472007",
"ISSN": "1939-3792",
"publisher": "Wiley",
"URL": "https://doi.org/10.1002/aur.70312",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
12
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1016/j.isci.2026.116458 [code]
Neural tracking of prosodic and statistical rhythms jointly supports artificial language learning.
Journal: iScience
In common: Statistics and Machine Learning Toolbox, cognitive, 13 references
[2] doi:10.7554/elife.109901
Infants at high and low likelihood for autism show different EEG developmental trajectories in speech tracking and statistical learning.
Journal: eLife
In common: autism, EEG, 12 references
[3] doi:10.1162/opmi.a.358 [code]
Tracking Visual Statistical Learning with Steady-State Visual Evoked Potentials: Effects of Exemplar and Category Information.
Journal: Open mind : discoveries in cognitive science
In common: EEG, cognitive, 11 references
[4] doi:10.1016/j.dcn.2026.101767
Neural correlates of learning speed reveal developmental differences in memory.
Journal: Developmental cognitive neuroscience
In common: 8 references
[5] doi:10.1016/j.celrep.2026.117590 [code]
Impaired behavioral inhibition in Fmr1 KO mice is linked to disrupted visual cortex theta oscillations.
Journal: Cell reports
In common: Statistics and Machine Learning Toolbox, autism, EEG, other condition, 5 references
[6] doi:10.1111/cogs.70220 [code]
Shared Neural Computations for Syntactic and Morphological Structures: Evidence From Mandarin Chinese.
Journal: Cognitive science
In common: ERPLAB, EEGLAB, Statistics and Machine Learning Toolbox, EEG, cognitive, 1 reference
[7] doi:10.1038/s41467-026-73878-4 [code]
Neural Response to Familiar Names Predicts Outcome of Comatose ICU Patients: A Prospective Observational Cohort Study.
Journal: Nature communications
In common: ERPLAB, EEGLAB, Statistics and Machine Learning Toolbox, EEG, other condition, 1 reference
[8] doi:10.1162/imag.a.1229 [code]
40 Hz audiovisual stimulation improves sustained attention and related brain oscillations.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: ERPLAB, EEGLAB, Statistics and Machine Learning Toolbox, EEG, 1 reference
[9] doi:10.1038/s41467-026-75843-7 [code]
Compressive learning scaffolds higher-order network structure to enhance human knowledge acquisition.
Journal: Nature communications
In common: shadedErrorBar, Statistics and Machine Learning Toolbox, cognitive, 2 references
[10] doi:10.1038/s41598-026-47785-z [code]
Modulations of the P3b effect as a function of bilingual language experience.
Journal: Scientific reports
In common: ERPLAB, EEGLAB, Statistics and Machine Learning Toolbox, EEG, cognitive

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.