analysis(matlab): per-variation subfolders (grouping x window) for the paper LME
Add make_variations.m + variation_analyze.m generating 20 self-contained subfolders under analysis/matlab/variations/, one per grouping x day-window, each with exactly three files: data.csv (curated subset), analyze.m (a simple standalone script fitting behavior ~ stim + day + stim:day + (1|rat) on the success COUNT), and result.txt (its output). Plus variations/SUMMARY.csv. Groupings (stim=1 / stim=0, other groups dropped): unmerge B2 vs A2 right_only B2+Right vs A2 (Box-A dropped) naive_a2 B2 vs A2+Naive (Right, Box-A dropped) naive_boxa B2 vs A2+Naive+Box-A (Right dropped) Windows: 0-10, 0-13, 0-5, 6-10, 6-13. All 20 have equal day coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
function make_variations()
|
||||
%MAKE_VARIATIONS Generate one self-contained subfolder per grouping x window.
|
||||
% MAKE_VARIATIONS() writes analysis/matlab/variations/<grouping>_<window>/
|
||||
% for every combination below, each holding exactly three files:
|
||||
% data.csv the curated data subset for that variation
|
||||
% analyze.m a simple, standalone MATLAB script (copy of
|
||||
% variation_analyze.m) that fits the paper's LME on data.csv
|
||||
% result.txt the text result that analyze.m produces
|
||||
% and a top-level variations/SUMMARY.csv indexing all variations.
|
||||
%
|
||||
% Groupings (stim = 1 treatment / stim = 0 control; all OTHER groups dropped):
|
||||
% unmerge Box-B2 vs Box-A2
|
||||
% right_only Box-B2 + Right-Elec. vs Box-A2 (Box-A dropped)
|
||||
% naive_a2 Box-B2 vs Box-A2 + Naive (Right, Box-A dropped)
|
||||
% naive_boxa Box-B2 vs Box-A2 + Naive + Box-A (Right dropped)
|
||||
% Windows: 0-10, 0-13, 0-5, 6-10, 6-13.
|
||||
%
|
||||
% The model in each analyze.m is the paper's:
|
||||
% behavior ~ stim + day + stim:day + (1|rat) (behavior = success COUNT).
|
||||
|
||||
thisDir = fileparts(mfilename('fullpath'));
|
||||
templateScript = fullfile(thisDir, 'variation_analyze.m');
|
||||
root = fullfile(thisDir, 'variations');
|
||||
if ~exist(root, 'dir'); mkdir(root); end
|
||||
|
||||
B2 = 'Electrode-Box-B2'; A2 = 'Electrode-Box-A2'; NAIVE = 'Naive';
|
||||
BOXA = 'Electrode-Box-A'; RIGHT = 'Right-Electrode';
|
||||
|
||||
% grouping name | treatment groups (stim=1) | control groups (stim=0)
|
||||
groupings = {
|
||||
'unmerge', {B2}, {A2}
|
||||
'right_only', {B2, RIGHT}, {A2}
|
||||
'naive_a2', {B2}, {A2, NAIVE}
|
||||
'naive_boxa', {B2}, {A2, NAIVE, BOXA}
|
||||
};
|
||||
|
||||
% window name | [loDay hiDay]
|
||||
windows = {
|
||||
'd0_10', [0 10]
|
||||
'd0_13', [0 13]
|
||||
'd0_5', [0 5]
|
||||
'd6_10', [6 10]
|
||||
'd6_13', [6 13]
|
||||
};
|
||||
|
||||
T = tdcs_load_data();
|
||||
allGroup = cellstr(T.group);
|
||||
|
||||
rows = {}; % accumulate SUMMARY rows
|
||||
for gi = 1:size(groupings, 1)
|
||||
gname = groupings{gi, 1};
|
||||
treat = groupings{gi, 2};
|
||||
ctrl = groupings{gi, 3};
|
||||
inTreat = ismember(allGroup, treat);
|
||||
inCtrl = ismember(allGroup, ctrl);
|
||||
|
||||
for wi = 1:size(windows, 1)
|
||||
wname = windows{wi, 1};
|
||||
w = windows{wi, 2};
|
||||
sel = (inTreat | inCtrl) & T.day >= w(1) & T.day <= w(2);
|
||||
|
||||
D = T(sel, :);
|
||||
stim = double(inTreat(sel));
|
||||
Dout = table(string(D.subject), string(D.group), D.day, D.success, ...
|
||||
D.total, stim, 'VariableNames', ...
|
||||
{'subject', 'group', 'day', 'success', 'total', 'stim'});
|
||||
|
||||
vname = [gname '_' wname];
|
||||
folder = fullfile(root, vname);
|
||||
if ~exist(folder, 'dir'); mkdir(folder); end
|
||||
writetable(Dout, fullfile(folder, 'data.csv'));
|
||||
copyfile(templateScript, fullfile(folder, 'analyze.m'));
|
||||
|
||||
try
|
||||
r = localRun(fullfile(folder, 'analyze.m'));
|
||||
rows(end + 1, :) = {vname, gname, wname, r.nRats, r.nObs, ...
|
||||
r.covEqual, r.interP, r.interEst, r.stimP, r.dayP}; %#ok<AGROW>
|
||||
fprintf(' %-16s N=%2d obs=%4d interaction p=%.4g (%+.2f) %s\n', ...
|
||||
vname, r.nRats, r.nObs, r.interP, r.interEst, ...
|
||||
localTern(r.covEqual, 'equal-cov', 'UNEQUAL-cov'));
|
||||
catch ME
|
||||
localWriteError(folder, ME);
|
||||
fprintf(2, ' %-16s ERROR: %s\n', vname, ME.message);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Top-level index of all variations.
|
||||
S = cell2table(rows, 'VariableNames', {'variation', 'grouping', 'window', ...
|
||||
'nRats', 'nObs', 'covEqual', 'interaction_p', 'interaction_est', ...
|
||||
'stim_p', 'day_p'});
|
||||
writetable(S, fullfile(root, 'SUMMARY.csv'));
|
||||
fprintf('\nWrote %d variations under %s\n(index: variations/SUMMARY.csv)\n', ...
|
||||
size(rows, 1), root);
|
||||
|
||||
end
|
||||
|
||||
function r = localRun(scriptPath)
|
||||
%LOCALRUN Execute one analyze.m in an isolated workspace and return its
|
||||
% VARRESULT struct. Isolation prevents the script's variables (D, m, ...)
|
||||
% from colliding with the generator's loop state.
|
||||
run(scriptPath);
|
||||
r = VARRESULT; %#ok<NODEF> (defined by the analyze.m script just run)
|
||||
end
|
||||
|
||||
function localWriteError(folder, ME)
|
||||
fid = fopen(fullfile(folder, 'result.txt'), 'w');
|
||||
fprintf(fid, 'ERROR fitting this variation:\n%s\n', getReport(ME, 'basic'));
|
||||
fclose(fid);
|
||||
end
|
||||
|
||||
function out = localTern(cond, a, b)
|
||||
if cond; out = a; else; out = b; end
|
||||
end
|
||||
Reference in New Issue
Block a user