sidescanpy.processing.layback#

Layback: move per-ping positions from the ship to the towfish.

A towed sonar sits behind (and below) the navigation antenna. When the recorded per-ping latitude / longitude are the ship’s, the "layback" step moves each ping astern along its heading by the tow-point offset plus the layback, and to starboard by the tow-point offset, before geometric and georef place the samples:

aft = tow_point_aft_m + layback_m starboard = tow_point_starboard_m

This is a fixed offset astern (the first-order model MB-System applies from recorded layback and lever arms). The towfish is assumed directly astern of the tow point on the ping’s heading_deg; course made good, cable catenary and tractrix models of a fish lagging in turns are not modelled.

Never double-applied: positions move only when the dataset’s position_source (set by the reader, see sidescanpy.core.schema) is "ship". "towfish" (the acquisition software already laid it back), "mixed" and "unknown" leave the dataset unchanged and log a WARNING saying why; a caller who knows better passes position_source.

Per-ping layback comes from layback_m (a scalar parameter overrides the variable). Where it is NaN and use_cable_out is set, the Pythagorean estimate sqrt(cable_out_m² − depth_m²) is used (tow-point height ignored). Pings left without a layback or heading are not moved and are counted in the history record.

The recorded positions are kept as latitude_before_layback / longitude_before_layback, so sidescanpy.processing.inversion.invert() can undo the step.

2026 rshomberg@uri.edu

Contents

LAT_BEFORE_VAR

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

LON_BEFORE_VAR

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

LAYBACK_MODEL

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

apply_layback

Move ship positions to the towfish (the "layback" step).

undo_layback

Restore the recorded positions and position source; drop the kept copies.

sidescanpy.processing.layback.LAT_BEFORE_VAR = 'latitude_before_layback'#

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

sidescanpy.processing.layback.LON_BEFORE_VAR = 'longitude_before_layback'#

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

sidescanpy.processing.layback.LAYBACK_MODEL = 'fixed_offset_astern'#

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

sidescanpy.processing.layback.apply_layback(ds, *, layback_m=None, tow_point_aft_m=None, tow_point_starboard_m=None, position_source=None, use_cable_out=True, ellipsoid='WGS84')#

Move ship positions to the towfish (the "layback" step).

Parameters:
dsxr.Dataset or SideScanSurvey

Frequency channel dataset. A SideScanSurvey is corrected frequency by frequency with the same arguments; a new survey is returned and the input is not modified.

layback_mfloat, optional

Layback for every ping (m). Default: the layback_m variable.

tow_point_aft_m, tow_point_starboard_mfloat, optional

Antenna-to-tow-point offset (m, aft and starboard positive). Default: the dataset attributes of the same name, else 0.

position_sourcestr, optional

What latitude / longitude are the position of, one of sidescanpy.core.schema.POSITION_SOURCES. Default: the dataset’s position_source attribute (unknown when absent). Positions move only for "ship".

use_cable_outbool, default True

Where layback_m is NaN, estimate it as sqrt(cable_out_m² − depth_m²).

ellipsoidstr, default “WGS84”

Ellipsoid for the geodesic offsets.

Returns:
xr.Dataset or SideScanSurvey

Same type as ds: a new dataset. When positions moved: latitude / longitude at the towfish, the recorded ones in latitude_before_layback / longitude_before_layback, position_source set to "towfish" and a "layback" history record. Otherwise the input, unchanged and without a record.

Raises:
ValueError

If the step was already applied, georef was applied before it (its per-sample positions would go stale; invert it first), or position_source is not a known value.

sidescanpy.processing.layback.undo_layback(ds, record)#

Restore the recorded positions and position source; drop the kept copies.

The history record is not removed here (invert() does that).