Skip to content

Add fix_rbc_release_tr.py for the C-PAC TR bandpass bug#342

Closed
nx10 wants to merge 1 commit into
mainfrom
scripts/fix-rbc-release-tr
Closed

Add fix_rbc_release_tr.py for the C-PAC TR bandpass bug#342
nx10 wants to merge 1 commit into
mainfrom
scripts/fix-rbc-release-tr

Conversation

@nx10
Copy link
Copy Markdown
Contributor

@nx10 nx10 commented May 22, 2026

For users who have already downloaded an RBC data release and want to fix the C-PAC TR/bandpass bug (#4 in docs/cpac_comparison.md) without re-running anything upstream.

How it works

Walks a release tree (sub-*/ses-*/func/) and for each functional run:

  1. Reads the correct TR from the native-space desc-preproc_bold.nii.gz header (or accepts --tr-override).
  2. Patches the template-space desc-head_bold.nii.gz header — released with pixdim[4]=0.0, which gets silently coerced to 1.0 by AFNI inside C-PAC and ends up driving the bandpass off by 2x.
  3. Re-runs nuisance regression + bandpass via apply_regression_bandpass (AFNI 3dTproject -bandpass) using C-PAC's raw (unfiltered) regressors as the ort matrix.
  4. Writes the fixed cleaned BOLD, matching bandpass-filtered regressors, and a JSON sidecar with provenance to a parallel --output-dir tree. Originals untouched.

Scope

Intentionally narrow — only fixes divergence #4. Downstream derivatives (ALFF, fALFF, ReHo, atlas timeseries, connectivity matrices) all sit downstream of the broken bandpass and are NOT regenerated; that's a follow-up if users want it (most of the RBC library functions are right there to call). Other divergences (#1 N4 discarded, #2 despike in template, #3 ALFF formula) are left as-is per the comparison doc's framing.

CLI

uv run scripts/fix_rbc_release_tr.py \
    --input-dir  /path/to/rbc_release \
    --output-dir /path/to/fixed_release \
    [--participant-label sub-X ...] \
    [--bandpass 0.01 0.1] \
    [--tr-override 2.0] \
    [--runner auto] \
    [--dry-run | --verify]

--verify does a sanity check on the first run: confirms head_bold has the broken TR and reports the expected TR from the native preproc_bold, so users can validate the bug is actually present before kicking off bulk work.

Other changes

  • Promotes rbc.core.functional.resampling._restore_tr to a public restore_tr (the script reuses it; internal callers + the longitudinal mock were updated).

Test plan

  • uv run pytest tests/unit/scripts/ — 8 new tests covering discovery, TR detection, dry-run, verify, participant-label filtering, and graceful skipping of incomplete runs.
  • uv run pytest tests/unit -m unit — 710 passed (longitudinal mock target updated).
  • uv run ruff check + uv run mypy on all touched files.
  • End-to-end smoke against the ds000001 fixture: discovery, TR detection, head_bold patching, 3dTproject command construction all verified. The actual AFNI call wasn't exercised here (Docker daemon was down locally) but the call site is the already-tested apply_regression_bandpass.

Lets users of an RBC data release re-derive the cleaned BOLD with a
correctly-bandpassed `3dTproject`, by patching the template-space
`desc-head_bold.nii.gz` header (TR=0.0 on disk) with the TR read from
the native-space `desc-preproc_bold.nii.gz` header before regression.

Only the bandpass bug (#4 in docs/cpac_comparison.md) is addressed.
Downstream derivatives (ALFF, ReHo, atlas timeseries, connectivity)
are not regenerated; users wanting those should recompute from the
fixed BOLD with their own tooling.

Also promotes `_restore_tr` to a public `restore_tr` for reuse by
external tooling.
@github-actions
Copy link
Copy Markdown

Coverage

Tests Skipped Failures Errors Time
799 6 💤 0 ❌ 0 🔥 11.831s ⏱️

@nx10
Copy link
Copy Markdown
Contributor Author

nx10 commented May 22, 2026

Closing to revise — will reopen after iteration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant