sidescanpy.processing.farrange#
Far-range noise detection and cropping.
Some surveys record a channel’s sample window well past where real
backscatter decays into noise — a per-survey acquisition setting, not
fixed by frequency. Past that point, raw amplitude doesn’t stay flat — it climbs back up,
new evidence for a hardware TVG/AGC artifact baked into the raw signal —
which apply_tvg()’s uncapped, monotonically-increasing gain formula
then massively over-amplifies (a ~57 dB overshoot measured on real data),
saturating percentile-based color scales and burying the real near-nadir
signal. This module detects that decay-then-rise pattern directly from
the uncorrected signal (and crops it out —
intentionally conservative: a channel with no detected rise is left
untouched, not cropped by a guessed constant, since the recorded window
length varies per survey.
Binning is done by raw sample index, not real range — this needs no geometric computation (no aux interpolation, no altitude), so it can run immediately after conversion, before any other correction step.
2026 rshomberg@uri.edu
Contents
Detect the sample index beyond which backscatter climbs back up after decaying into its real noise floor. |
|
Crop one channel's far-range noise (the |
|
Apply |
- sidescanpy.processing.farrange.detect_far_range_cutoff_sample(ds, *, n_bins=40, min_valid_fraction=0.5, rise_threshold_db=3.0, margin_bins=1)#
Detect the sample index beyond which backscatter climbs back up after decaying into its real noise floor.
Works on the uncorrected signal: any recorded radiometric steps are inverted first (
sidescanpy.processing.inversion.uncorrected_backscatter()), so it can run before or after TVG. Bin statistics are accumulated in ping blocks, so memory stays bounded on large (or dask-backed) datasets.Bins the uncorrected signal (converted to dB) by sample index across
n_binsroughly-equal bins, finds the peak bin (the strongest mean return) among bins with enough finite samples to be statistically reliable, then finds the minimum-mean bin after that peak (the real far-range floor — searched only post-peak so a legitimate near-nadir ramp-up is never mistaken for the floor). If any later, equally-reliable bin’s mean then risesrise_threshold_dbor more above that floor, returns a cropped sample count (the floor bin’s end, plusmargin_binsof slack). If no such rise is found, returnsNone— nothing should be cropped.A cutoff whose slant range is not beyond the median
altitude_mis rejected with a WARNING andNoneis returned: on recordings that include the transmit pulse and the water column, the “floor” found is the water column and the “rise” is the seafloor return.- Parameters:
- dsxr.Dataset
A single frequency channel dataset.
- n_binsint, default 40
Number of sample-index bins to divide the sample axis into.
- min_valid_fractionfloat, default 0.5
A bin is “reliable” only if at least this fraction of its
n_pings * n_channels * bin_sizecells are finite.- rise_threshold_dbfloat, default 3.0
How far above the detected floor a later, reliable bin’s mean must climb to count as “the noise climbing back up”.
- margin_binsint, default 1
Extra bins kept past the detected floor bin.
- Returns:
- int or None
Sample count to crop to (
ds.isel(sample=slice(0, result))), orNoneif no crop is warranted.
- sidescanpy.processing.farrange.crop_far_range(ds, *, cutoff_sample=None, n_bins=40, min_valid_fraction=0.5, rise_threshold_db=3.0, margin_bins=1)#
Crop one channel’s far-range noise (the
"crop_farrange"step).Detects the cutoff with
detect_far_range_cutoff_sample()(the detection keyword arguments are passed through) unlesscutoff_sampleis given. A channel with no detected artifact is left untouched. Either way a"crop_farrange"history record is appended (with the resolvedcutoff_sample,Nonewhen nothing was cropped), so a later run knows detection already happened.Not invertible: cropped samples are gone (re-convert from the source file to get them back).
dsmay also be aSideScanSurvey: each frequency is cropped at its own detected cutoff and a new survey is returned (the input is not modified).
- sidescanpy.processing.farrange.crop_far_range_noise(survey, **detect_kwargs)#
Apply
crop_far_range()to every frequency channel insurvey.- Parameters:
- surveySideScanSurvey
Mutated in place (frequency channels replaced) and returned.
- **detect_kwargs
Passed through to
crop_far_range().
- Returns:
- (survey, cutoffs)
cutoffs:freq_key -> cropped sample count, orNonefor channels left unchanged.