Divide the solver's source filter back out of the recombination - #144
Draft
lispandfound wants to merge 1 commit into
Draft
Divide the solver's source filter back out of the recombination#144lispandfound wants to merge 1 commit into
lispandfound wants to merge 1 commit into
Conversation
lispandfound
force-pushed
the
nzvm/bb-matched-filter
branch
from
September 2, 2026 02:23
427f137 to
85f21f1
Compare
lispandfound
force-pushed
the
nzvm/bb-matched-filter
branch
from
September 2, 2026 02:52
85f21f1 to
dc8667f
Compare
Both solvers low-pass their *source* time functions: SW4 through its
`prefilter` command, EMOD3D through `bfilt` with a corner derived from
`min_vs` and the grid spacing. The wave equation is linear, so filtering
the source is equivalent to filtering every trace -- which means the LF
leg arrives at `bb-sim` already low-passed, and the matched pair then
low-passes it a second time.
The result is a hole around the merge frequency: the matched high-pass
and low-pass are power-complementary by construction, but only if each
leg is filtered once. `tests/test_bb_filters.py` measures the hole and
then measures that each correction closes it.
Because the filter is applied to the source rather than the output,
`bb-sim` can divide it back out here instead of the solver having to be
re-run. `--solver` reads the filter the realisation actually specifies
(rather than assuming one), and refuses to guess: an SW4 prefilter that
is not a lowpass, or an EMOD3D configuration that also high-passes, is
an error rather than a correction for the wrong thing.
`--filter` chooses which leg absorbs it:
lf restores the low-frequency leg exactly. Needs the largest boost.
hf fills the missing power from the high-frequency side instead.
Cannot restore below the merge frequency, where the HF leg
carries nothing to scale up.
both one factor on both legs. Best conditioned -- `current_power` is
bounded below by the high-pass leg -- and restores the power sum
exactly, at the cost of touching both legs.
`MAX_BOOST` caps any correction at 10x. The two real configurations need
about 2.4x; anything near the cap means the source filter rolls off
faster than the target and the leg is being reconstructed from content
that is not there. `warn_if_ill_conditioned` says so up front.
Without `--solver` the recombination is bit-for-bit unchanged: the
correction is applied after the matched pair rather than in place of it,
and the gains are exactly 1. Verified against the previous commit's
output.
What was applied is written into the broadband file's attributes.
Without that the correction is invisible downstream and two files that
differ by it look identical.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lispandfound
force-pushed
the
nzvm/bb-matched-filter
branch
from
September 4, 2026 01:44
dc8667f to
09437b1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Both solvers low-pass their source time functions: SW4 through its
prefiltercommand, EMOD3D throughbfiltwith a corner derived frommin_vsand the grid spacing. The wave equation is linear, so filteringthe source is equivalent to filtering every trace -- which means the LF
leg arrives at
bb-simalready low-passed, and the matched pair thenlow-passes it a second time.
The result is a hole around the merge frequency: the matched high-pass
and low-pass are power-complementary by construction, but only if each
leg is filtered once.
tests/test_bb_filters.pymeasures the hole andthen measures that each correction closes it.
Because the filter is applied to the source rather than the output,
bb-simcan divide it back out here instead of the solver having to bere-run.
--solverreads the filter the realisation actually specifies(rather than assuming one), and refuses to guess: an SW4 prefilter that
is not a lowpass, or an EMOD3D configuration that also high-passes, is
an error rather than a correction for the wrong thing.
--filterchooses which leg absorbs it:lf restores the low-frequency leg exactly. Needs the largest boost.
hf fills the missing power from the high-frequency side instead.
Cannot restore below the merge frequency, where the HF leg
carries nothing to scale up.
both one factor on both legs. Best conditioned --
current_powerisbounded below by the high-pass leg -- and restores the power sum
exactly, at the cost of touching both legs.
MAX_BOOSTcaps any correction at 10x. The two real configurations needabout 2.4x; anything near the cap means the source filter rolls off
faster than the target and the leg is being reconstructed from content
that is not there.
warn_if_ill_conditionedsays so up front.Without
--solverthe recombination is bit-for-bit unchanged: thecorrection is applied after the matched pair rather than in place of it,
and the gains are exactly 1. Verified against the previous commit's
output.
What was applied is written into the broadband file's attributes.
Without that the correction is invisible downstream and two files that
differ by it look identical.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Stack created with GitHub Stacks CLI • Give Feedback 💬