% Variation analysis -- the paper's linear mixed model on the successful-reach % COUNT, fit on this folder's curated data subset. % % model: behavior ~ stim + day + stim:day + (1|rat) % behavior = successful reaches (count per session) % stim = 1 for the treatment group(s), 0 for the control group(s) % day = training day within this window (0 = first analyzed day) % rat = subject (random intercept) % % Self-contained: reads data.csv beside this script and writes result.txt. % Run headless from this folder with: matlab -batch "analyze" % (This is a copy of analysis/matlab/variation_analyze.m; see make_variations.m.) here = fileparts(mfilename('fullpath')); if isempty(here); here = pwd; end vname = regexprep(here, '.*[/\\]', ''); % folder name = variation id D = readtable(fullfile(here, 'data.csv'), 'TextType', 'string'); tbl = table(D.success, D.day - min(D.day), double(D.stim), categorical(D.subject), ... 'VariableNames', {'behavior', 'day', 'stim', 'rat'}); m = fitlme(tbl, 'behavior ~ stim + day + stim:day + (1|rat)'); C = m.Coefficients; A = anova(m); ci = coefCI(m); gi = @(t) find(strcmp(C.Name, t), 1); ga = @(t) find(strcmp(A.Term, t), 1); row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%8.3f p=%.4g\n', nm, ... C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t))); maxT = max(D.day(D.stim == 1)); minT = min(D.day(D.stim == 1)); maxC = max(D.day(D.stim == 0)); minC = min(D.day(D.stim == 0)); if abs(maxT - maxC) > 2 cov = '** WARNING: unequal day coverage -- interaction may be confounded. **'; else cov = '(equal day coverage over this window)'; end ii = gi('day:stim'); pI = C.pValue(ii); eI = C.Estimate(ii); if pI >= 0.05 verdict = 'n.s. -- slopes parallel (no differential learning rate)'; elseif eI > 0 verdict = 'SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates)'; else verdict = 'SIGNIFICANT negative -- treatment improves SLOWER (groups converge)'; end bar = repmat('=', 1, 78); raw = regexprep(evalc('disp(m)'), '', ''); s = sprintf('%s\nVARIATION: %s\n%s\n', bar, vname, bar); s = [s sprintf('model: behavior ~ stim + day + stim:day + (1|rat) (behavior = success COUNT)\n')]; s = [s sprintf('day = training day within window (0 = first analyzed day)\n')]; s = [s sprintf('treatment (stim=1): %s\n', strjoin(cellstr(unique(D.group(D.stim == 1))), ', '))]; s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim == 0))), ', '))]; s = [s sprintf('N = %d rats, %d sessions raw day coverage: treat %d..%d, control %d..%d\n', ... numel(unique(D.subject)), height(D), minT, maxT, minC, maxC)]; s = [s sprintf('%s\n\n%s\nFULL MODEL SUMMARY -- fitlme\n%s\n%s\n', cov, bar, bar, raw)]; s = [s sprintf('%-26s %-13s %-13s %s\n%s\n', 'effect', 't (df)', 'F (df1)', 'p', repmat('-', 1, 66))]; s = [s row('stim x day (interaction)', 'day:stim')]; s = [s row('day (learning)', 'day')]; s = [s row('stim (main, window start)', 'stim')]; s = [s sprintf('interaction 95%% CI: [%+.2f, %+.2f]\n', ci(ii, 1), ci(ii, 2))]; s = [s sprintf('INTERPRETATION: stim x day interaction %s (p=%.4g, slope diff=%+.2f)\n', verdict, pI, eI)]; s = [s sprintf('Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.\n')]; fprintf('%s', s); fid = fopen(fullfile(here, 'result.txt'), 'w'); fprintf(fid, '%s', s); fclose(fid); % Machine-readable handoff for the summary table (see make_variations.m). VARRESULT = struct('name', vname, 'nRats', numel(unique(D.subject)), ... 'nObs', height(D), 'interP', pI, 'interEst', eI, ... 'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ... 'covEqual', abs(maxT - maxC) <= 2);