sidescanpy.io.dispatch#

Format-dispatching helpers for sonar file ingestion.

Given a list of file paths, pick the right per-format reader/converter by extension and produce a validated SideScanSurvey. Used by any script or caller that wants “just give me a survey from these files” without hand-rolling the .jsf/.sdf/.xtf branch itself.

2026 rshomberg@uri.edu

Contents

detect_format

Detect sonar file format from extension; raise on mixed extensions.

read_and_convert

Read sonar files and convert to a SideScanSurvey.

segment_stem

Output stem of segment index (1-based) of count.

read_and_convert_segments

Read one raw sonar file into one survey per constant-range segment.

SONAR_FORMATS

Raw formats read_and_convert() reads.

CATALOG_JSF_DISCOVER

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

CATALOG_SDF_KLEIN

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

find_sonar_files

Raw sonar files directly in input_dir (not recursive), sorted.

load_survey

Read path as a survey, whatever it is.

detect_catalog_format

Target-catalog format of the directory source, from its own contents.

read_target_catalog

Read the target catalog in directory source.

sidescanpy.io.dispatch.detect_format(input_paths)#

Detect sonar file format from extension; raise on mixed extensions.

Extensions are compared case-insensitively (.XTF is "xtf").

Parameters:
input_pathspath or list of paths

Candidate sonar files (str or Path). All must share the same extension — this function is for the “merge these into one survey” case; batch callers processing files independently should call it once per file instead of once for a whole directory.

Returns:
str

One of: “jsf”, “sdf”, “xtf”.

Raises:
ValueError

If extensions are mixed, or the (single) extension isn’t supported.

sidescanpy.io.dispatch.read_and_convert(input_paths, fmt, survey_name=None, *, nav_crs=None)#

Read sonar files and convert to a SideScanSurvey.

Parameters:
input_pathspath or list of paths

Paths (str or Path) to .jsf, .sdf or .xtf files (all same format); a single path is one file.

fmtstr

“jsf”, “sdf” or “xtf”.

survey_namestr, optional

Survey name. Defaults to first input file’s stem.

nav_crsint, str or pyproj.CRS, optional

XTF only: projected CRS of files with NavUnits 0 (see sidescanpy.io.xtf.convert()). Ignored for JSF and SDF.

Returns:
SideScanSurvey
sidescanpy.io.dispatch.segment_stem(stem, index, count)#

Output stem of segment index (1-based) of count.

stem itself for a single segment, else <stem>_seg01, <stem>_seg02, … (at least two digits).

sidescanpy.io.dispatch.read_and_convert_segments(path, *, survey_name=None, min_pings=50, nav_crs=None)#

Read one raw sonar file into one survey per constant-range segment.

A .jsf file gives one survey, exactly as read_and_convert(). .xtf and .sdf files are split at sample-rate (range-setting) changes (split_by_sample_rate(), split_by_sample_rate()) and each kept run is converted on its own, so every survey has the right sample_rate_hz; runs shorter than min_pings are dropped (for XTF, counted in each survey’s xtf_pings_dropped_short_runs attribute).

Parameters:
pathPath

One .jsf, .sdf or .xtf file.

survey_namestr, optional

Base name; defaults to path.stem.

min_pingsint, default 50

XTF and SDF: shortest run kept when a file is split.

nav_crsint, str or pyproj.CRS, optional

XTF only: projected CRS of a file with NavUnits 0 (see sidescanpy.io.xtf.convert()). Ignored for JSF and SDF.

Returns:
list[tuple[str, SideScanSurvey]]

(output_stem, survey) per segment, in file order. The stem is the base name for a single segment, else <base>_seg01, <base>_seg02, … (see segment_stem()); each survey is named after its stem.

Raises:
ValueError

Unsupported extension, or an XTF or SDF file whose runs are all shorter than min_pings.

sidescanpy.io.dispatch.SONAR_FORMATS = ('jsf', 'sdf', 'xtf')#

Raw formats read_and_convert() reads.

sidescanpy.io.dispatch.CATALOG_JSF_DISCOVER = 'jsf_discover'#

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.io.dispatch.CATALOG_SDF_KLEIN = 'sdf_klein'#

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.io.dispatch.find_sonar_files(input_dir, input_format='auto')#

Raw sonar files directly in input_dir (not recursive), sorted.

Parameters:
input_dirpath

Directory to search.

input_format{“auto”, “jsf”, “sdf”, “xtf”}, default “auto”

"auto" returns *.jsf, *.sdf and *.xtf files. .xtf matches in any letter case (.XTF is common); .jsf and .sdf match lower case only.

Raises:
ValueError

Unknown input_format.

sidescanpy.io.dispatch.load_survey(path, *, chunks=None)#

Read path as a survey, whatever it is.

A .ss.h5 (or .h5/.hdf5) file is read with read_survey() (chunks passed through); a raw .jsf/.sdf/.xtf file is converted in memory with read_and_convert() (chunks ignored).

sidescanpy.io.dispatch.detect_catalog_format(source)#

Target-catalog format of the directory source, from its own contents.

Dispatches on the catalog files present, not on the paired survey’s format (a JSF survey can be labelled in SonarWiz and vice versa).

Returns:
str

CATALOG_SDF_KLEIN (Target_*.tgt) or CATALOG_JSF_DISCOVER (*.target).

Raises:
ValueError

Both kinds present (ambiguous), or neither.

sidescanpy.io.dispatch.read_target_catalog(source)#

Read the target catalog in directory source.

Returns (format, targets) with format from detect_catalog_format(). Klein targets come back without a resolved position; see sidescanpy.targets.correlate for resolving them against .ss.h5 files.