feat(notch): tap caps 512 → 1024; the clamp warning reports the estimated achievable rejection #48

Merged
ykp merged 2 commits from notch-taps-1024 into master 2026-09-29 14:39:37 +02:00
Owner

Operator request: raise MAX_TAPS to 1024 for steeper notches / higher stopband attenuation — plus the small changes that make the 60 dB target reachable in most cases.

Changes

  1. bandpass.MAX_TAPS 512 → 1024 and DEFAULT_NOTCH_TAP_CAP 512 → 1024 (the notch cap is an independent setting defaulting to the band filter's scale, per spec §5.3.3 — kept in sync).
  2. The clamp warning now reports the estimated achievable rejection — the Kaiser-form inverse (≈ 8 + 14.36·Δf_norm·cap dB) against the record's target, naming the two 60 dB levers (widen the transition / raise the cap). Previously the warning only said the rejection "may fall below the target" with no number.
  3. Spec §5.3.3 updated (defaults, warning content, the 60 dB rule of thumb).

Measured impact (Fe = 200 MHz)

Transition Order estimate @ 1024 taps Result
≥ 1 MHz ≤ 725 taps no clamp 60 dB target reached
0.5 MHz 1449 taps clamps (1025 taps) −57.5 dB measured (Kaiser-form estimate said ~45 — remez equiripple beats it)
0.25 MHz ~2900 taps clamps warning states the shortfall

So with the bump, the 60 dB target is reached for transitions ≥ ~1 MHz; even 0.5 MHz lands within ~3 dB of it.

Suggestions for consistently hitting 60 dB (for the operator)

  1. Widen the record's transition band — the dominant lever: at Fe = 200 MHz, Transition ≥ ~1 MHz reaches 60 dB within the 1024-tap cap; 2 MHz leaves comfortable headroom (the default fixture's −73 dB).
  2. Allow 0.1 dB passband ripple (a global setting, default 0.05): a larger allowed ripple lets the equiripple design buy rejection depth at the same tap count (measured in the explorer's sweep: ripple 0.1 dB @ 128 taps already reaches −60 dB).
  3. The clamp warning is now a decision tool: it states the estimated shortfall, so an operator seeing "~45 dB against a 60 dB target" knows exactly which lever to move.
  4. Not pursued (assessed, no gain): cascading two half-depth notch designs (order composes — no tap savings), raising remez grid_density (marginal convergence gain, more compute), per-waveform caps (the global setting suffices).

Gate

  • pytest: 1288 passed / 64 skipped (headless tier), coverage 93.59 %
  • ruff + mypy: clean
Operator request: raise `MAX_TAPS` to 1024 for steeper notches / higher stopband attenuation — plus the small changes that make the **60 dB target reachable in most cases**. ## Changes 1. **`bandpass.MAX_TAPS` 512 → 1024** and **`DEFAULT_NOTCH_TAP_CAP` 512 → 1024** (the notch cap is an independent setting defaulting to the band filter's scale, per spec §5.3.3 — kept in sync). 2. **The clamp warning now reports the estimated achievable rejection** — the Kaiser-form inverse (`≈ 8 + 14.36·Δf_norm·cap` dB) against the record's target, naming the two 60 dB levers (widen the transition / raise the cap). Previously the warning only said the rejection "may fall below the target" with no number. 3. Spec §5.3.3 updated (defaults, warning content, the 60 dB rule of thumb). ## Measured impact (Fe = 200 MHz) | Transition | Order estimate | @ 1024 taps | Result | |---|---|---|---| | ≥ 1 MHz | ≤ 725 taps | no clamp | **60 dB target reached** | | 0.5 MHz | 1449 taps | clamps (1025 taps) | **−57.5 dB measured** (Kaiser-form estimate said ~45 — remez equiripple beats it) | | 0.25 MHz | ~2900 taps | clamps | warning states the shortfall | So with the bump, the 60 dB target is reached for transitions ≥ ~1 MHz; even 0.5 MHz lands within ~3 dB of it. ## Suggestions for consistently hitting 60 dB (for the operator) 1. **Widen the record's transition band — the dominant lever**: at `Fe = 200 MHz`, `Transition ≥ ~1 MHz` reaches 60 dB within the 1024-tap cap; 2 MHz leaves comfortable headroom (the default fixture's −73 dB). 2. **Allow 0.1 dB passband ripple** (a global setting, default 0.05): a larger allowed ripple lets the equiripple design buy rejection depth at the same tap count (measured in the explorer's sweep: ripple 0.1 dB @ 128 taps already reaches −60 dB). 3. **The clamp warning is now a decision tool**: it states the estimated shortfall, so an operator seeing "~45 dB against a 60 dB target" knows exactly which lever to move. 4. Not pursued (assessed, no gain): cascading two half-depth notch designs (order composes — no tap savings), raising remez `grid_density` (marginal convergence gain, more compute), per-waveform caps (the global setting suffices). ## Gate - `pytest`: **1288 passed / 64 skipped** (headless tier), coverage **93.59 %** - `ruff` + `mypy`: clean
feat(notch): tap caps 512 -> 1024; the clamp warning reports the estimated achievable rejection (operator request)
All checks were successful
test / test (ubuntu-latest) (pull_request) Successful in 2m46s
870624bf1c
- bandpass.MAX_TAPS 512 -> 1024 (operator request: steeper notches,
  higher stopband attenuation before the order clamp engages) and
  DEFAULT_NOTCH_TAP_CAP follows (the notch cap is an independent
  setting defaulting to the band filter's scale, spec §5.3.3).
- The clamp warning now REPORTS the estimated achievable rejection
  (the Kaiser-form inverse, ~8 + 14.36·dF_norm·cap dB) against the
  record's target, with the two 60 dB levers named: widen the record's
  transition band, or raise the notch tap cap setting.
- Measured (Fe = 200 MHz): transitions >= 1 MHz fit the estimate under
  the cap (725 taps, no clamp) and reach the 60 dB target; the 0.5 MHz
  case clamps at 1025 taps and still measures -57.5 dB at the band
  centre (remez equiripple beats the Kaiser-form ~45 dB estimate).
- tests: notch-cap default premise (1024), dialog field-shape
  premise ('1024'); the cap-param test keeps an explicit 512 design
  (still exercises the clamp); spec §5.3.3 updated (default, warning
  content, the 60 dB rule of thumb).

Gate: pytest 1288 passed / 64 skipped (headless tier), coverage
93.59 %; ruff + mypy clean.
feat(notch): default passband ripple 0.05 -> 0.1 dB (operator-accepted downgrade)
All checks were successful
test / test (ubuntu-latest) (pull_request) Successful in 2m52s
0f5694e677
- DEFAULT_NOTCH_PASSBAND_RIPPLE_DB 0.05 -> 0.1 dB (operator decision:
  the equiripple design buys rejection depth at the same tap count with
  a larger allowed passband ripple — measured in the explorer's sweep:
  0.1 dB @ 128 taps already reaches -60 dB). The transition band is
  UNTOUCHED (operator instruction) — records stay operator data.
- The validator docstring, the default premise tests (Settings defaults
  + tolerant-load), the settings-dialog field-shape premise ('0.1') and
  spec §5.3.3 (default + the rule-of-thumb sentence) follow. The
  stopband-weight math tests keep explicit 0.05 dB calls (they pin the
  formula, not the default).

Gate: pytest 1288 passed / 64 skipped (headless tier), coverage
93.59 %; ruff + mypy clean.
ykp merged commit 3707399163 into master 2026-09-29 14:39:37 +02:00
ykp deleted branch notch-taps-1024 2026-09-29 14:39:37 +02:00
Sign in to join this conversation.
No description provided.