sidescanpy.processing.profiles#

Range- and sample-binned backscatter profiles.

Binning primitives used by the TVG range-correction fit in sidescanpy.processing.range_correction and by the TVG analysis in sidescanpy.analysis.tvg (which re-exports both functions).

2026 rshomberg@uri.edu

Contents

backscatter_vs_range

Bin samples by range and return per-bin mean/median/std/p10/p90/count.

median_level_profile

Median level of linear amplitude per range bin, in dB re 1.

backscatter_vs_sample

Bin samples by absolute sample index (not range) and return per-bin stats.

sidescanpy.processing.profiles.backscatter_vs_range(ds, value_var, range_var='ground_range_m', bin_width_m=5.0, exclude_below_db=None)#

Bin samples by range and return per-bin mean/median/std/p10/p90/count.

Parameters:
dsxr.Dataset

Any dataset with value_var and range_var (same shape, arbitrary dims — flattened internally). Does not need to be a full valid sidescan schema dataset.

value_varstr

Name of the backscatter (or other) variable to aggregate.

range_varstr, default “ground_range_m”
bin_width_mfloat, default 5.0
exclude_below_dbfloat, optional

If given, samples with value_var < exclude_below_db are excluded before binning (e.g. Known Issue #5’s floor-clipped samples). Default None (include everything) is deliberate: whether to exclude floor-clipped samples is one of the open questions this tool exists to help answer, not a decision to bake in silently.

Returns:
pd.DataFrame

Columns: range_min_m, range_max_m, mean, median, std, p10, p90, count. Empty (zero rows) if no samples survive filtering.

sidescanpy.processing.profiles.median_level_profile(ds, value_var='backscatter_intensity', range_var='slant_range_m', *, bin_width_m=1.0, channel=None, min_range_m=None, exclude_water_column=True, min_count=50, dither='auto', seed=0)#

Median level of linear amplitude per range bin, in dB re 1.

Every bin from 0 to the largest range is returned, so the rows form a regular range axis; a bin with fewer than min_count samples has a NaN level. The median is taken on the linear values and converted with 20 log10; a non-positive median gives NaN.

Parameters:
dsxr.Dataset

Channel dataset with value_var (linear amplitude) and range_var of the same shape, or broadcastable to it.

value_varstr, default “backscatter_intensity”
range_varstr, default “slant_range_m”
bin_width_mfloat, default 1.0
channelint, optional

Use one side only (0 port, 1 starboard). None pools both.

min_range_mfloat, optional

Drop samples at or below this range, e.g. the survey’s median altitude (one cut for all pings keeps each bin’s pings the same).

exclude_water_columnbool, default True

Drop samples where ground_range_m is NaN (slant range below the altitude). No-op when ground_range_m is missing.

min_countint, default 50

Fewer samples than this in a bin give a NaN level.

ditherbool or “auto”, default “auto”

Add a uniform offset in [-0.5, 0.5) to each sample before taking medians, which spreads integer samples over their unit interval so the medians do not stick to whole numbers. "auto" dithers only when every finite sample is a whole number.

seedint, default 0

Seed of the dither generator (the profile is reproducible).

Returns:
pd.DataFrame

Columns range_min_m, range_max_m, range_m (bin center), median (linear), level_db and count. df.attrs["dithered"] records whether dither was applied.

sidescanpy.processing.profiles.backscatter_vs_sample(ds, value_var, bin_width=50, exclude_below_db=None)#

Bin samples by absolute sample index (not range) and return per-bin stats.

Works before geometric ranges exist, and for artifacts fixed in sample position rather than range (e.g. a leading blanking run).

Parameters:
dsxr.Dataset

Must have a sample dimension and value_var defined over it (other dims are flattened).

value_varstr
bin_widthint, default 50

Bin width in sample-index units.

exclude_below_dbfloat, optional

See backscatter_vs_range().

Returns:
pd.DataFrame

Columns: sample_min, sample_max, mean, median, std, p10, p90, count.