sidescanpy.processing.slicing#

Slicing operations for SideScan frequency channels.

Every function takes an xr.Dataset (one frequency channel) and returns a new xr.Dataset – the sliced version of the input. Empty slices (zero pings or zero samples) are valid and return an empty-but- schema-valid dataset. slice_survey maps any of them over every frequency of a SideScanSurvey.

Slicing is structural: backscatter values, processing_level, and processing_history are preserved. No values are modified.

Available slicing functions:

  • slice_by_pings — by ping index range

  • ping_windows — (start, stop) ranges tiling a ping axis, for windowed reads

  • slice_by_samples — by absolute sample coordinate range

  • slice_by_range — by slant range in metres

  • slice_by_time — by ping timestamp range (supports str or datetime64)

  • slice_by_bbox — by lat/lon bounding box (per-ping by default, per-sample with use_per_sample=True)

  • slice_by_ground_range — by maximum ground range (requires ground_range_m to be present, run compute_geometric_ranges first)

2026 rshomberg@uri.edu

Contents

slice_by_pings

Return a new dataset with pings [start, stop).

ping_windows

[start, stop) windows of window_pings covering 0..n_pings.

slice_by_samples

Return a new dataset with samples whose index is in [start, stop).

slice_by_range

Return a new dataset with samples whose slant range is in [min_m, max_m].

slice_by_time

Return a new dataset with pings whose timestamp is in [start, stop).

slice_by_bbox

Return a new dataset containing pings whose position is within the bbox.

slice_by_ground_range

Return a new dataset with samples whose ground_range_m is ≤ range_max_m.

slice_survey

Apply a Dataset slicer to every frequency of survey.

sidescanpy.processing.slicing.slice_by_pings(ds, *, start=0, stop=None)#

Return a new dataset with pings [start, stop).

Parameters:
dsxr.Dataset

Input frequency-channel dataset.

startint, default 0

First ping index to include.

stopint, optional

One past the last ping index to include. Defaults to n_pings.

Returns:
xr.Dataset

New dataset with the selected ping range.

sidescanpy.processing.slicing.ping_windows(n_pings, window_pings, overlap_pings=0)#

[start, stop) windows of window_pings covering 0..n_pings.

Consecutive windows share overlap_pings pings; the last window ends at n_pings (and may be shorter). No windows for n_pings == 0.

Raises:
ValueError

window_pings < 1, or overlap_pings not in [0, window_pings).

sidescanpy.processing.slicing.slice_by_samples(ds, *, start=0, stop=None)#

Return a new dataset with samples whose index is in [start, stop).

Selection is by the absolute integer sample coordinate (label based, counted from the transmit: 0 is normally the first recorded sample of the ping), so slicing an already-sliced dataset keeps meaning the same samples. Datasets with no sample coordinate fall back to positional selection.

Parameters:
dsxr.Dataset

Input frequency-channel dataset.

startint, default 0

First absolute sample index to include.

stopint, optional

One past the last absolute sample index. Defaults to unbounded.

Returns:
xr.Dataset

New dataset with the selected sample range.

sidescanpy.processing.slicing.slice_by_range(ds, min_m=None, max_m=None)#

Return a new dataset with samples whose slant range is in [min_m, max_m].

Slant range is sample * c / (2 * fs) from the absolute sample coordinate, using the mean per-ping sample interval (the same sound_vel_ms/sample_rate_hz logic as compute_geometric_ranges). Because sound velocity varies slightly per ping, the cut is made at a single sample boundary for the whole dataset.

Parameters:
dsxr.Dataset

Input frequency-channel dataset.

min_m, max_mfloat, optional

Inclusive slant-range bounds in metres. None means unbounded.

sidescanpy.processing.slicing.slice_by_time(ds, *, start=None, stop=None)#

Return a new dataset with pings whose timestamp is in [start, stop).

Parameters:
dsxr.Dataset

Input frequency-channel dataset.

startstr, np.datetime64, or None

Inclusive lower bound. Strings are parsed as ISO-format. None means no lower bound.

stopstr, np.datetime64, or None

Exclusive upper bound. None means no upper bound.

Returns:
xr.Dataset

New dataset containing only pings whose time falls in the range.

sidescanpy.processing.slicing.slice_by_bbox(ds, *, lat_min, lat_max, lon_min, lon_max, use_per_sample=False)#

Return a new dataset containing pings whose position is within the bbox.

Parameters:
dsxr.Dataset

Input frequency-channel dataset.

lat_min, lat_maxfloat

Latitude bounds (inclusive). degrees_north.

lon_min, lon_maxfloat

Longitude bounds (inclusive). degrees_east.

use_per_samplebool, default False

If False, a ping is kept when its per-ping latitude and longitude are both within the bbox.

If True, a ping is kept when any of its samples (latitude_per_sample and longitude_per_sample) is within the bbox. Requires compute_georeferencing to have been run.

Returns:
xr.Dataset

New dataset with pings within the bbox.

sidescanpy.processing.slicing.slice_by_ground_range(ds, *, range_max_m)#

Return a new dataset with samples whose ground_range_m is ≤ range_max_m.

Trims the sample dimension to the maximum sample index where any ping/channel has ground_range_m ≤ range_max_m. Pings with shorter in-range coverage retain NaN beyond their individual cutoffs.

Parameters:
dsxr.Dataset

Input frequency-channel dataset. Must have ground_range_m (run compute_geometric_ranges first).

range_max_mfloat

Maximum ground range to retain (meters).

Returns:
xr.Dataset

New dataset with truncated sample dim.

sidescanpy.processing.slicing.slice_survey(survey, fn, **kwargs)#

Apply a Dataset slicer to every frequency of survey.

Returns a new survey with the same metadata and each frequency replaced by fn(ds, **kwargs). Aux streams are not carried over.