feat(chirp): normalise the Double Chirp to full scale; band-filter constants 512 taps / 1.08 shape factor #39

Merged
ykp merged 1 commit from double-chirp-normalize into chirp-directions-integration 2026-09-27 19:32:48 +02:00
Owner

Operator-requested follow-up: a normalisation step for the Double Chirp plus two band-filter constant changes.

Stacked on #38 (chirp-directions close-out, still open) — base is chirp-directions-integration; retarget to master after #38 merges (the only shared file, doc/spec.md, has disjoint hunks).

1. Double Chirp normalisation (revises the ticket-41 A1 default)

generate_double_chirp now adds a normalisation step: after summing the up + down bases at the optimal phase θ*, the combined base's peak is scaled to full scale (1.0) before the phase-2 repeat. Each component still carries its full band Level gain (the ticket-41 semantics), but without the step the sum can approach 2× a single chirp's peak — the normalisation keeps the phase-2 repeat and the CFR/PAPR post-chain unclipped. Docstring and spec §5.2.1c updated to the revised semantics.

2. Band-filter constants (operator request)

  • bandpass.MAX_TAPS: 4096 → 512
  • bandpass.SHAPE_FACTOR: 1.1 → 1.08
  • pipeline.py docstring follows; the test_pipeline.py reference helpers consume the constants dynamically so the bitwise-pinned band-stage comparisons stay exact.

Tests

  • test_bandpass.py: the *_FTRANS fixtures now derive from bandpass.SHAPE_FACTOR instead of a hardcoded 1.1 (future constant changes propagate); docstring/comment updates.
  • test_double_chirp.py: the A1 no-compensation test is replaced by test_combined_base_normalised_to_full_scale (peak == 1.0 for both the single-block and repeated outputs); the element-wise base test normalises its expected vector the same way.

Gate

  • pytest: 1239 passed / 63 skipped (headless tier, includes the #38 stack)
  • ruff + mypy: clean (69 files)
  • Smoke: Double Chirp peak exactly 1.000000 (same full scale as a single chirp).
Operator-requested follow-up: a normalisation step for the Double Chirp plus two band-filter constant changes. > **Stacked on #38** (chirp-directions close-out, still open) — base is `chirp-directions-integration`; retarget to `master` after #38 merges (the only shared file, `doc/spec.md`, has disjoint hunks). ## 1. Double Chirp normalisation (revises the ticket-41 A1 default) `generate_double_chirp` now adds a **normalisation step**: after summing the up + down bases at the optimal phase `θ*`, the combined base's **peak is scaled to full scale (1.0)** before the phase-2 repeat. Each component still carries its full band `Level` gain (the ticket-41 semantics), but without the step the sum can approach 2× a single chirp's peak — the normalisation keeps the phase-2 repeat and the CFR/PAPR post-chain unclipped. Docstring and spec §5.2.1c updated to the revised semantics. ## 2. Band-filter constants (operator request) - `bandpass.MAX_TAPS`: **4096 → 512** - `bandpass.SHAPE_FACTOR`: **1.1 → 1.08** - `pipeline.py` docstring follows; the `test_pipeline.py` reference helpers consume the constants dynamically so the bitwise-pinned band-stage comparisons stay exact. ## Tests - `test_bandpass.py`: the `*_FTRANS` fixtures now **derive from `bandpass.SHAPE_FACTOR`** instead of a hardcoded 1.1 (future constant changes propagate); docstring/comment updates. - `test_double_chirp.py`: the A1 no-compensation test is replaced by `test_combined_base_normalised_to_full_scale` (peak == 1.0 for both the single-block and repeated outputs); the element-wise base test normalises its expected vector the same way. ## Gate - `pytest`: **1239 passed / 63 skipped** (headless tier, includes the #38 stack) - `ruff` + `mypy`: clean (69 files) - Smoke: Double Chirp peak **exactly 1.000000** (same full scale as a single chirp).
- chirp.py: generate_double_chirp adds a NORMALISATION step — after
  summing the up + down bases at the optimal phase, the combined base's
  peak is scaled to full scale (1.0) before the phase-2 repeat. This
  revises the ticket-41 A1 default (each component still carries its
  full band Level; without the step the sum can approach 2x a single
  chirp's peak) so the phase-2 repeat and the CFR post-chain receive an
  unclipped signal. Docstring + spec 5.2.1c updated to the revised
  semantics.
- bandpass.py: MAX_TAPS 4096 -> 512, SHAPE_FACTOR 1.1 -> 1.08 (operator
  request); pipeline.py docstring follows.
- tests: test_bandpass.py fixtures derive FTRANS from the module
  constant (bandpass.SHAPE_FACTOR) instead of a hardcoded 1.1;
  test_double_chirp.py — the A1 no-compensation test is replaced by
  test_combined_base_normalised_to_full_scale (peak == 1.0 for both the
  single-block and repeated outputs) and the element-wise base test
  normalises its expected vector the same way; test_pipeline.py
  docstring comment updated.

Gate: pytest 1203 passed / 63 skipped (headless tier, master + this
stack), ruff + mypy clean.
ykp merged commit 1cf6400bce into chirp-directions-integration 2026-09-27 19:32:48 +02:00
Sign in to join this conversation.
No description provided.