hans / hans/barakeet

late_perceptual_significance.py notebook + Snakefile rule -> site_results.parquet + population headline

Open
#10 0 comments 0 reactions 0 assignees View on GitHub
ready-for-agent
Dominant language
Jupyter Notebook
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Parent

Plan: `docs/superpowers/plans/2026-07-20-causal46-late-perceptual-significance.md` (Step 3 + Step 5 rule). The core vertical slice — end-to-end runnable via smoke snakemake.

## What to build

A new notebook `notebooks/causal46_joined/late_perceptual_significance.py` (Jupytext percent-format) plus a `late_perceptual_significance` Snakemake rule, that turns the persisted B4 bootstrap into a per-cell late within-completion percept significance test and a population-level headline.

Per cell over the **full 187 powered B4 cells** `(subject, electrode_idx, phoneme_pair, word_end)`:
- Build post-acoustic candidate windows: `smin >= phon_smax`, `smax <= round((OFFSET_DICT[we] + 0.1 - epoch_tmin) * epoch_sfreq)` (D4 — matches existing window logic).
- Form the observed curve (median over replicates of `mean_diff_raw` per window — two-tailed signed `/n/-/d/`, raw, D1) and the R coherent null curves (recovered signed `null_raw`, or `|.|` for two-tailed) from `b4_bootstrap.parquet`.
- Compute `tfce_max_abs`, two-tailed `tfce_emp_p` (max-TFCE null, via #9 helpers), the knob-free integral robustness stat/p (D3), and the optional split-half sign-agreement column (D7).
- Drop tied cells from the gate but keep them in the parquet with `is_tied=True` (D2).
- BH-FDR over the 187 `tfce_emp_p`; count-vs-null headline vs `Binomial(187, 0.05)` (D5). Same per-cell p-values feed both operating points — one pass.
- Join read-only `manual_behav_late` for later calibration use (D6).

Emits `outputs/causal46_joined/late_perceptual_significance/site_results.parquet` (schema per plan Outputs) and a basic `population_summary.pdf` carrying the count-vs-null headline + BH-FDR survivor count.

## Acceptance criteria

- [ ] `site_results.parquet` has one row per powered B4 cell with all columns in the plan's Outputs schema (`tfce_peak`, `tfce_max_abs`, `tfce_emp_p`, `tfce_gate_pass`, `tfce_p_fdr`, `tfce_fdr_pass`, `integral_stat`, `integral_emp_p`, `splithalf_sign_agree`, `is_tied`, `manual_behav_late`, window bounds).
- [ ] Grid validated (contiguous, stride == window_size) reusing existing assertions; per-cell row-count == R x n_windows asserted.
- [ ] Population headline computed: count with uncorrected TFCE p<0.05 vs Binomial(187, 0.05), plus BH-FDR survivor count. Family = 187, not 84.
- [ ] `late_perceptual_significance` Snakemake rule added (inputs `b4_bootstrap.parquet`, `b4_per_cell.parquet`; outputs the parquet + PDF); notebook params match the Snakefile `run_notebook`.
- [ ] Runs clean end-to-end under the smoke config: `CONFIG_FILE=config.smoke.yaml uv run snakemake --configfile config.smoke.yaml -j1` (via `uv run`; `snakemake -n` dry-run clean).

## Blocked by

- #8 (tied-cell audit — confirms the null is usable / drop-and-document)
- #9 (TFCE + max-null helpers in `_windows.py`)

Contributor guide

No contributing guide indexed for this repository

Research direction

Read the parent plan and inspect the existing B4 inputs, #8 tied-cell audit, and #9 helpers before starting. Add notebooks/causal46_joined/late_perceptual_significance.py and the matching Snakefile rule using b4_bootstrap.parquet and b4_per_cell.parquet. Done means the parquet and population_summary.pdf are produced and the smoke Snakemake command completes cleanly.

Written by the indexing model from the issue text.

Assessment

Tech stack
jupyter-notebook, python
Domain
build-system, data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.