feat(matlab): print full native fitlme/fitglme summary in every scenario

Add tdcs_model_summary as the single place that renders a fitted model
verbatim (disp(model) with the Command-Window <strong> markup stripped),
and route every report through it so all scenarios emit the complete
model-fitting output:

- tdcs_report: adds the learning-rate GLMM's full summary (count/rate
  already had theirs); localCleanDisp now delegates to the shared helper.
- tdcs_lme_report / tdcs_paper_lme: embed the full fitlme summary before
  the curated effect table.
- tdcs_phase_lme: appends each phase's full fitlme summary.

Tests: tReport asserts 3 native summaries in a GLMM report; tLme asserts
the lme_*/paper_*/phase_* reports embed 1/1/3 summaries with markup
stripped. Suite 39/39.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Experiments DB Dev
2026-07-20 14:21:34 -04:00
parent d59ff2b659
commit 0e9263b958
41 changed files with 4637 additions and 7 deletions
+199
View File
@@ -0,0 +1,199 @@
==============================================================================
tDCS GLM report -- scenario: mergeA2_d0_10
==============================================================================
merge key: mergeA2 day window: 0..10 observations: 126
==============================================================================
DESCRIPTIVES
==============================================================================
group n_subj n_sessions mean_success mean_rate max_day
--------------------------------------------------------------------------
Electrode-Box-B2 4 44 68.3 0.541 10
Electrode-Box-A2 4 39 54.0 0.452 10
Naive 4 43 46.8 0.440 10
==============================================================================
(A) LEVEL / COUNT -- Poisson GLMM (subject random intercept)
==============================================================================
Generalized linear mixed-effects model fit by PL
Model information:
Number of observations 126
Fixed effects coefficients 5
Random effects coefficients 12
Covariance parameters 1
Distribution Poisson
Link Log
FitMethod MPL
Formula:
success ~ 1 + group + day_c + day_c2 + (1 | subject)
Model fit statistics:
AIC BIC LogLikelihood Deviance
297.29 314.31 -142.65 285.29
Fixed effects coefficients (95% CIs):
Name Estimate SE tStat DF
{'(Intercept)' } 4.2656 0.092258 46.236 121
{'group_Electrode-Box-A2'} -0.12664 0.12996 -0.97447 121
{'group_Naive' } -0.41983 0.12988 -3.2324 121
{'day_c' } 0.20187 0.0052718 38.293 121
{'day_c2' } -0.024068 0.0015714 -15.317 121
pValue Lower Upper
9.3543e-79 4.083 4.4483
0.33177 -0.38392 0.13065
0.0015818 -0.67696 -0.1627
1.7547e-69 0.19144 0.21231
4.2028e-30 -0.027179 -0.020957
Random effects covariance parameters:
Group: subject (12 Levels)
Name1 Name2 Type Estimate
{'(Intercept)'} {'(Intercept)'} {'std'} 0.17893
Group: Error
Name Estimate
{'sqrt(Dispersion)'} 1
==============================================================================
(B) LEVEL / RATE -- Binomial GLMM (subject random intercept)
==============================================================================
Generalized linear mixed-effects model fit by PL
Model information:
Number of observations 124
Fixed effects coefficients 5
Random effects coefficients 12
Covariance parameters 1
Distribution Binomial
Link Logit
FitMethod MPL
Formula:
success ~ 1 + group + day_c + day_c2 + (1 | subject)
Model fit statistics:
AIC BIC LogLikelihood Deviance
363.74 380.67 -175.87 351.74
Fixed effects coefficients (95% CIs):
Name Estimate SE tStat DF
{'(Intercept)' } 0.15282 0.1244 1.2285 119
{'group_Electrode-Box-A2'} -0.28467 0.17474 -1.6291 119
{'group_Naive' } -0.57945 0.17473 -3.3162 119
{'day_c' } 0.21677 0.0069268 31.294 119
{'day_c2' } -0.013732 0.0021989 -6.2451 119
pValue Lower Upper
0.22169 -0.0935 0.39915
0.10595 -0.63068 0.061343
0.0012101 -0.92543 -0.23346
2.8838e-59 0.20305 0.23048
6.7844e-09 -0.018086 -0.0093781
Random effects covariance parameters:
Group: subject (12 Levels)
Name1 Name2 Type Estimate
{'(Intercept)'} {'(Intercept)'} {'std'} 0.23963
Group: Error
Name Estimate
{'sqrt(Dispersion)'} 1
==============================================================================
(C) LEARNING RATE -- Poisson GLMM (group x day interaction)
==============================================================================
Generalized linear mixed-effects model fit by PL
Model information:
Number of observations 126
Fixed effects coefficients 7
Random effects coefficients 12
Covariance parameters 1
Distribution Poisson
Link Log
FitMethod MPL
Formula:
success ~ 1 + day_c2 + group*day_c + (1 | subject)
Model fit statistics:
AIC BIC LogLikelihood Deviance
304.66 327.35 -144.33 288.66
Fixed effects coefficients (95% CIs):
Name Estimate SE tStat
{'(Intercept)' } 4.2968 0.091824 46.794
{'group_Electrode-Box-A2' } -0.15174 0.12947 -1.172
{'group_Naive' } -0.50686 0.13029 -3.8902
{'day_c' } 0.18436 0.0072535 25.417
{'day_c2' } -0.024459 0.001577 -15.509
{'group_Electrode-Box-A2:day_c'} 0.014228 0.010876 1.3082
{'group_Naive:day_c' } 0.051203 0.011091 4.6167
DF pValue Lower Upper
119 1.7772e-78 4.115 4.4786
119 0.24354 -0.4081 0.10462
119 0.00016554 -0.76486 -0.24887
119 6.5517e-50 0.17 0.19872
119 2.3835e-30 -0.027581 -0.021336
119 0.19332 -0.0073071 0.035763
119 9.9271e-06 0.029242 0.073164
Random effects covariance parameters:
Group: subject (12 Levels)
Name1 Name2 Type Estimate
{'(Intercept)'} {'(Intercept)'} {'std'} 0.17742
Group: Error
Name Estimate
{'sqrt(Dispersion)'} 1
Per-animal OLS slope test (Box-B2 vs Box-A2), cluster-honest:
Per-subject OLS slope of success vs day: Box-B2 mean=9.71, Box-A2 mean=9.18
Welch two-sided p=0.556, Mann-Whitney p=0.686 (nB=4, nA=4) -> parallel learning (no slope difference detected)
(Reference only: the GLMM group x day_c joint F-test gives p=0.0001, but with just
observation-level DF (df2=119) it is ANTICONSERVATIVE for this few-subject design and is
NOT the basis for the conclusion above.)
==============================================================================
INTERPRETATION
==============================================================================
Note: these are subject-level GLMMs (Laplace-approximated fitglme), not the
Python reference's population-average GEE -- directions/magnitudes should agree,
exact ratios and p-values will differ.
Anchor check -- H2: Box-B2 BETTER than Box-A2 (the two anchors must differ)
[count/level] Box-B2 = 1.14x Box-A2 (one-sided p=0.1649) -> not supported
[rate/level ] Box-B2 = 1.33x Box-A2 (one-sided p=0.0517) -> not supported
Per-animal (Box-B2 n=4 vs Box-A2 n=4), pure stats (no GLME):
count (per-subject mean success): Welch two-sided p=0.0230, Mann-Whitney one-sided (B2>A2) p=0.0143
rate (per-subject pooled success/total): Welch two-sided p=0.0689, Mann-Whitney one-sided (B2>A2) p=0.0571
(No unknown groups -- they were merged into the anchors; only the H2 anchor
contrast applies.)
==============================================================================
CAVEATS
==============================================================================
- Tiny groups: each arm has only n=3-4 subjects (Naive n=4; anchor arms n=3-5
depending on merge), and -- in unmerged scenarios -- each unknown condition
(Electrode-Box-A, Right-Electrode) has only n=1 subject. Treat every group
comparison here as preliminary.
- Single-subject classification: for a 1-subject unknown, 'matches anchor X'
means 'not statistically distinguishable from X', NOT proof of equivalence;
inference with a single subject in a group is fragile.
- Count vs rate: 'success' alone is a raw count; the rate model
(success/attempts) is the fairer accuracy comparison when attempt counts differ
between groups.