Skip to content

Give spectral ranges and bandpasses in the units of any axis - #29

Merged
jtravs merged 4 commits into
mainfrom
fix/plotting-spec-range
Oct 26, 2026
Merged

jtravs merged 4 commits into
mainfrom
fix/plotting-spec-range

Conversation

@jtravs

@jtravs jtravs commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Problem

prop_2d, spec_1d and spectrogram accept axis={'wavelength','f','omega'} but took
their spectral window only as wavelength_range. A frequency map could not be given a
range in hertz, nor one starting at 0 Hz, which is an infinite wavelength. Every
bandpass= keyword (the accessors, the compressors, time_1d, prop_2d, energy) was
likewise a wavelength range or a ready-made array.

Changes

Plot ranges in the units of the axis.

  • prop_2d, spec_1d and spectrogram take spec_range, in m, Hz or rad/s as axis
    says. This is the same name and meaning as get_spectral_density(spec_range=...).
  • Without spec_range they show their previous default wavelength range, converted to
    the axis. spec_1d's default is now the named constant
    DEFAULT_SLICE_WAVELENGTH_RANGE.
  • style.spectral_limits is replaced by wavelength_to_axis(axis, wavelength_range),
    which returns SI limits on any axis.
prop_2d(run, "f", spec_range=(0.0, 2e15))
prop_2d(run, "omega", spec_range=wavelength_to_axis("omega", (600e-9, 1100e-9)))

Bandpass windows on any axis.

  • solprop.processing.Passband(limits, axis="wavelength", width=None) carries its own
    axis and edge width. Every bandpass= keyword accepts it through
    spectra._as_window, so no function gains a keyword.
  • bandpass(grid, limits, *, axis=..., width=...) builds the same window; its first
    argument is renamed from wavelength_limits to limits.
  • A frequency band may start at zero (a low-pass band). Wavelength limits must be
    positive and frequency limits must not be negative.
  • The edge width is in rad/s on every axis, because the taper is drawn on the ω grid.
    Luna's 3-tuple does the same.
  • A bare pair is still a wavelength range everywhere. A band's units never follow the
    axis a plot is drawn on, so the same call selects the same light however the result
    is displayed.
energy(run, bandpass=Passband((0.0, 375e12), "f"))
time_1d(run, bandpass=Passband((0.3e15, 0.45e15), "f"))

The design follows Luna.jl's Processing.window_maybe, which accepts a wavelength
2-tuple, a 3-tuple adding an ω edge width, a 4-tuple of taper points, a window vector or
a function. Here the wavelength pair and the array forms carry over unchanged, and the
explicit Passband type replaces meaning-by-tuple-length.

Breaking, with no aliases (nothing is public yet): wavelength_range= on the three plot
functions, style.spectral_limits, and bandpass(..., wavelength_limits=...) as a
keyword. Positional calls to bandpass are unaffected.

Docs

  • The user guide (plotting and processing pages) explains both, and their snippets run.
  • The changelog has two entries.
  • The tutorials and worked examples use the renamed keyword.
  • The ten worked examples that call the plots were re-run with poe docs-examples on an
    Apple M5 Max (23.5 min in all), and their output is committed.

Tests

  • New tests cover a hertz range on prop_2d and on spectrogram, an angular-frequency
    range on spec_1d, and the default range on a frequency axis.
  • wavelength_to_axis: c/λ and 2πc/λ.
  • Passband and bandpass(axis=...): f and ω windows equal the wavelength window, a
    zero lower edge, refusals, and an accessor taking a Passband.
  • Ran locally: tests/processing, tests/plotting, tests/test_sol.py, the guide
    snippets, and the doctests of the changed modules (756 passed); basedpyright and ruff
    are clean on the changed files. CI runs the full gate.

🤖 Generated with Claude Code

jtravs and others added 3 commits October 26, 2026 19:25
prop_2d, spec_1d and spectrogram took their spectral window only as
wavelength_range, so a frequency or angular-frequency axis could not be
given a range in Hz or rad/s, nor one starting at zero. They now take
spec_range in the SI units of `axis`, like get_spectral_density; left
out, it is the previous default wavelength range on that axis.
style.spectral_limits is replaced by wavelength_to_axis, which converts
a wavelength range to any axis. No alias: nothing is public yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A bandpass pair is still a wavelength range, m. Passband(limits, axis,
width) carries its own axis (m, Hz or rad/s) and edge width, and every
bandpass= keyword accepts it through _as_window, so the accessors, the
compressors and the plots take it with no new keywords. A frequency
band may start at zero. The builder takes the same axis and its first
argument is renamed to limits; the taper width stays in rad/s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ten worked examples that pass a spectral range to prop_2d or
spec_1d now say spec_range, so their committed output was stale. Re-run
with `poe docs-examples` on an Apple M5 Max: 23.5 min in all. The
figures are unchanged apart from round-off in the noise floor of the
tapered-capillary mode-energy panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 26, 2026 20:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@read-the-docs-community

read-the-docs-community Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Main's mode_average=True rewrite of the Raman comb worked example
conflicted with this branch's spec_range rename in its generated
output. The merged script is main's with spec_range; the example was
re-run with `poe docs-examples plot_04_raman_comb_supercontinuum` on an
Apple M5 Max (2.2 min), figures unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@jtravs
jtravs merged commit 5acb0ea into main Oct 26, 2026
31 checks passed
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.

2 participants