|
12 | 12 | outfname = outfname(strcmp(spm_file(outfname,'ext'),'set')); |
13 | 13 | segments = reshape(str2double(unique(regexp(spm_file(outfname,'basename'),'(?<=seg-)[0-9]+','match','once'))),1,[]); |
14 | 14 | conds = regexp(spm_file(outfname(endsWith(spm_file(outfname,'basename'),'seg-1')),'basename'),'(?<=_)[A-Z-0-9]+','match','once'); |
15 | | - condnum = cellfun(@(x) str2double(regexp(x,'(?<=-)[0-9]+','match')), conds); |
| 15 | + condname = cellfun(@(x) regexp(x,'[a-zA-Z0-9]+(?=-)','match','once'), conds, 'UniformOutput', false); |
| 16 | + condnum = cellfun(@(x) str2double(regexp(x,'(?<=-)[0-9]+','match')), conds); |
16 | 17 |
|
17 | 18 | % init summary |
18 | 19 | % - first session |
|
28 | 29 | case 'unloaded', EL.reload; |
29 | 30 | end |
30 | 31 | for c = 1:numel(conds) |
31 | | - subjtrials{c} = logical(sparse(numel(segments),MAXNTRIAL)); |
| 32 | + subjtrials.(condname{c}) = logical(sparse(numel(segments),MAXNTRIAL)); |
32 | 33 | for s = segments |
33 | 34 | segoutfname = outfname(endsWith(spm_file(outfname,'basename'),sprintf('seg-%d',s))); |
34 | 35 | if numel(segoutfname) ~= numel(conds), aas_log(aap,true,'All segments MUST have all conditions'); end |
|
42 | 43 | utrials = cellfun(@get_eventvalue, {eeg.urevent.type})'; |
43 | 44 | indtrials = cumsum(utrials == condnum(c)); |
44 | 45 |
|
45 | | - subjtrials{c}(s,indtrials([trials.urevent])) = true; |
| 46 | + subjtrials.(condname{c})(s,indtrials([trials.urevent])) = true; |
46 | 47 | end |
47 | | - subjtrials{c}(:,max(indtrials)+1:end) = []; |
| 48 | + subjtrials.(condname{c})(:,max(indtrials)+1:end) = []; |
48 | 49 | end |
49 | 50 | EL.unload; |
50 | 51 |
|
|
57 | 58 | for c = 1:numel(conds) |
58 | 59 | ax = nexttile; |
59 | 60 | hold on |
60 | | - arrayfun(@(s) plot(find(subjtrials{c}(s,:)),-s,'b*','MarkerSize',7), 1:numel(segments)) |
| 61 | + arrayfun(@(s) plot(find(subjtrials.(condname{c})(s,:)),-s,'b*','MarkerSize',7), 1:numel(segments)) |
61 | 62 | hold off |
62 | 63 | ylim([-max(segments+0.5),-0.5]); yticks(-max(segments):-1); |
63 | 64 | if c == 1, yticklabels(arrayfun(@(x) sprintf('segment %d',x),max(segments):-1:1,'UniformOutput',false)); |
64 | 65 | else, yticklabels({}); |
65 | 66 | end |
66 | | - xlim([0 size(subjtrials{c},2)]); |
| 67 | + xlim([0 size(subjtrials.(condname{c}),2)]); |
67 | 68 | title(ax, conds{c}); |
68 | 69 | end |
69 | 70 | print(f,'-djpeg','-r300',fn); |
|
73 | 74 | aap.report.(aap.tasklist.currenttask.name).alltrials{subj,sess} = subjtrials; |
74 | 75 |
|
75 | 76 | % table |
| 77 | + condcount = table(... |
| 78 | + 'Size',[numel(segments) numel(fieldnames(subjtrials))],... |
| 79 | + 'VariableNames',fieldnames(subjtrials),... |
| 80 | + 'VariableTypes',repmat({'single'},1,numel(fieldnames(subjtrials)))); |
76 | 81 | aap = aas_report_add(aap,subj,'<table id="data"><tr>'); |
77 | 82 | aap = aas_report_add(aap,subj,'<th>Segment</th>'); |
78 | 83 | for c = 1:numel(conds) |
|
82 | 87 | for s = segments |
83 | 88 | aap = aas_report_add(aap,subj,'<tr>'); |
84 | 89 | aap = aas_report_add(aap,subj,sprintf('<td>segment %d</td>',s)); |
85 | | - for c = 1:numel(conds) |
86 | | - condcount(s,c) = nnz(subjtrials{c}(s,:)); |
87 | | - aap = aas_report_add(aap,subj,sprintf('<td>%d</td>',condcount(s,c))); |
| 90 | + for cond = fieldnames(subjtrials)' |
| 91 | + condcount.(cond{1})(s) = nnz(subjtrials.(cond{1})(s,:)); |
| 92 | + aap = aas_report_add(aap,subj,sprintf('<td>%d</td>',condcount.(cond{1})(s))); |
| 93 | + if condcount.(cond{1})(s) == 0, condcount.(cond{1})(s) = NaN; end |
88 | 94 | end |
89 | 95 | aap = aas_report_add(aap,subj,'</tr>'); |
90 | 96 | end |
91 | 97 | aap = aas_report_add(aap,subj,'</table>'); |
92 | | - condcount(condcount==0) = NaN; % zero epoch should be the ones omitted |
93 | 98 | aap.report.(aap.tasklist.currenttask.name).condcount{subj,sess} = condcount; |
94 | 99 |
|
95 | 100 | case 'summary' |
96 | 101 | % missing data |
97 | | - isTrialMissing = cellfun(@isempty, aap.report.(aap.tasklist.currenttask.name).alltrials(:,sess)); |
98 | | - isCondcountMissing = cellfun(@(cc) isempty(cc) || (isscalar(cc) && isnan(cc)), aap.report.(aap.tasklist.currenttask.name).condcount(:,sess)); |
99 | | - lastSubjCondcount = find(~isCondcountMissing,1,'last'); |
| 102 | + isSubjMissing = cellfun(@isempty, aap.report.(aap.tasklist.currenttask.name).alltrials(:,sess)); |
| 103 | + maxCondNum = max(cellfun(@(cc) size(cc,2), aap.report.(aap.tasklist.currenttask.name).condcount(:,sess))); |
| 104 | + lastSubjCondcount = find(cellfun(@(cc) size(cc,2)==maxCondNum, aap.report.(aap.tasklist.currenttask.name).condcount(:,sess)),1,'last'); |
100 | 105 |
|
101 | 106 | % update conditions and sessions based on the last subject with no missing data |
102 | | - outfname = cellstr(aas_getfiles_bystream(aap,'meeg_session',[lastSubjCondcount sess],'meeg','output')); |
103 | | - outfname = outfname(strcmp(spm_file(outfname,'ext'),'set')); |
104 | | - segments = reshape(str2double(unique(regexp(spm_file(outfname,'basename'),'(?<=seg-)[0-9]+','match','once'))),1,[]); |
105 | | - conds = regexp(spm_file(outfname(endsWith(spm_file(outfname,'basename'),'seg-1')),'basename'),'(?<=_)[A-Z-0-9]+','match','once'); |
| 107 | + segments = 1:size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},1); |
| 108 | + conds = aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess}.Properties.VariableNames; |
106 | 109 |
|
107 | 110 | if ~isfield(aap.report.(aap.tasklist.currenttask.name),'summarysessions') |
108 | 111 | [~, aap.report.(aap.tasklist.currenttask.name).summarysessions] = aas_getN_bydomain(aap,aap.tasklist.currenttask.domain,lastSubjCondcount); |
|
119 | 122 | aap = aas_report_add(aap,'er',['<h3>Session: ' aap.acq_details.meeg_sessions(sess).name '</h3>']); |
120 | 123 |
|
121 | 124 | % Boxplot for each condition |
122 | | - jitter = 0.1; % jitter around position |
| 125 | + jitter = 0.1; % jitter around position (for every possible) |
123 | 126 | jitter = (... |
124 | | - 1+(rand([sum(~isCondcountMissing),size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},1)])-0.5) .* ... |
125 | | - repmat(jitter*2./[1:size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},1)],sum(~isCondcountMissing),1)... |
| 127 | + 1+(rand([numel(isSubjMissing),numel(segments)])-0.5) .* ... |
| 128 | + repmat(jitter*2./segments,numel(isSubjMissing),1)... |
126 | 129 | ) .* ... |
127 | | - repmat([1:size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},1)],sum(~isCondcountMissing),1); |
| 130 | + repmat(segments,numel(isSubjMissing),1); |
128 | 131 |
|
129 | 132 | condcountFn = fullfile(aas_getstudypath(aap),['diagnostic_' mfilename '_' aap.acq_details.meeg_sessions(sess).name '_conditioncount.jpg']); |
130 | 133 | condcountFig = figure; condcountFig.Position = [0 0 200*numel(conds) 600*numel(segments)]; |
|
134 | 137 | trialcountFig = figure; trialcountFig.Position = [0 0 1080 100*numel(conds)]; |
135 | 138 | tiledlayout(trialcountFig,numel(conds),1,'TileSpacing','tight'); |
136 | 139 |
|
137 | | - for c = 1:size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},2) |
| 140 | + for c = 1:numel(conds) |
| 141 | + isCondcountMissing = cellfun(@(cc) isempty(cc) || ~any(strcmp(conds{c},cc.Properties.VariableNames)), aap.report.(aap.tasklist.currenttask.name).condcount(:,sess)); |
138 | 142 | figure(condcountFig); ax = nexttile; hold on; |
139 | | - boxplot(cell2mat(cellfun(@(cc) cc(:,c), aap.report.(aap.tasklist.currenttask.name).condcount(~isCondcountMissing,sess), 'UniformOutput', false)')',... |
| 143 | + boxplot(cell2mat(cellfun(@(cc) cc.(conds{c})(:), aap.report.(aap.tasklist.currenttask.name).condcount(~isCondcountMissing,sess), 'UniformOutput', false)')',... |
140 | 144 | 'label',arrayfun(@(x) sprintf('Segment %d',x), 1:size(aap.report.(aap.tasklist.currenttask.name).condcount,3), 'UniformOutput', false)); |
141 | | - for seg = 1:size(aap.report.(aap.tasklist.currenttask.name).condcount{lastSubjCondcount,sess},1) |
142 | | - scatter(jitter(:,seg),cellfun(@(cc) cc(seg,c), aap.report.(aap.tasklist.currenttask.name).condcount(~isCondcountMissing,sess)),'k','filled','MarkerFaceAlpha',0.4); |
| 145 | + for seg = segments |
| 146 | + scatter(jitter(~isCondcountMissing,seg),cellfun(@(cc) cc.(conds{c})(seg), aap.report.(aap.tasklist.currenttask.name).condcount(~isCondcountMissing,sess)),'k','filled','MarkerFaceAlpha',0.4); |
143 | 147 | end |
144 | 148 | boxValPlot{c} = getappdata(getappdata(gca,'boxplothandle'),'boxvalplot'); |
145 | 149 | title(ax,conds{c}); |
146 | 150 |
|
147 | 151 | figure(trialcountFig); ax = nexttile; |
148 | | - tmp = cellfun(@(trl) full(trl{c}), aap.report.(aap.tasklist.currenttask.name).alltrials(~isTrialMissing,sess), 'UniformOutput', false); |
| 152 | + tmp = cellfun(@(trl) full(trl.(conds{c})), aap.report.(aap.tasklist.currenttask.name).alltrials(~isCondcountMissing,sess), 'UniformOutput', false); |
149 | 153 | maxNTrials = max(cellfun(@numel, tmp)); |
150 | 154 | for su = 1:numel(tmp) |
151 | 155 | tmp{su}(end+1:maxNTrials) = false; |
|
176 | 180 | aap = aas_report_add(aap,'er',sprintf('<th>Outliers</th>')); |
177 | 181 | end |
178 | 182 | aap = aas_report_add(aap,'er','</tr>'); |
179 | | - for seg = 1:size(aap.report.(aap.tasklist.currenttask.name).condcount{subj,sess},1) |
| 183 | + for seg = segments |
180 | 184 | aap = aas_report_add(aap,'er','<tr>'); |
181 | 185 | aap = aas_report_add(aap,'er',sprintf('<td>segment %d</td>',seg)); |
182 | 186 | for c = 1:numel(conds) % for each condition |
|
338 | 342 | else |
339 | 343 | missingEp = arrayfun(@(ep) isempty(ep.eventtype) || ~any(strcmp(cellstr(ep.eventtype), ev.eventvalue)), epochEEG.epoch); |
340 | 344 | end |
341 | | - if any(missingEp) |
| 345 | + if size(epochEEG.data,3) > 1 && any(missingEp) |
342 | 346 | % - insert marking event into the middle of the trial |
343 | 347 | mEEG = segEEG; |
344 | 348 | deltaLat = (ev.trlshift + mean(ev.eventwindow))/1000*mEEG.srate; |
|
0 commit comments