sidescanpy.io.jsf.reader#

JSF file reading, parsing, and inspection utilities.

This module provides: 1. Parse JSF binary files into message objects (streaming or bulk) 2. Inspect and debug JSF messages (slice, filter, export) 3. Export messages to JSON or other formats for inspection

The module focuses on raw message access without intermediate formats. For analysis/conversion, use the converter module to transform to standard schema.

2026 rshomberg@uri.edu

Contents

read_jsf

Parse all messages from a JSF binary file.

read_jsf_iter

Parse messages from JSF file as generator (memory efficient).

get_messages_by_index

Retrieve JSF messages by index range (slicing).

filter_messages_by_type

Filter messages by type name.

filter_messages_by_frequency

Filter SonarDataMessages by transmit frequency.

get_message_statistics

Get statistics about a collection of messages.

export_messages_to_json

Export messages to JSON for inspection/debugging.

export_messages_by_type_to_json

Export messages to separate JSON files organized by type.

save_messages_to_pickle

Save parsed messages to pickle file for caching during testing.

load_messages_from_pickle

Load parsed messages from pickle file.

sidescanpy.io.jsf.reader.read_jsf(fpath, N=None)#

Parse all messages from a JSF binary file.

Reads JSF binary format and deserializes messages sequentially until end-of-file or limit reached. Each message is validated and deserialized.

Parameters:
fpathPath

Path to JSF binary file.

Nint, optional

Maximum number of messages to read. If None (default), read all.

Returns:
list[JSFMessage]

List of parsed message objects in order.

Raises:
FileNotFoundError

If JSF file does not exist.

Examples

>>> messages = read_jsf(Path("survey.jsf"))
>>> print(f"Read {len(messages)} messages")
>>> # Read first 1000 messages only
>>> messages = read_jsf(Path("survey.jsf"), N=1000)
sidescanpy.io.jsf.reader.read_jsf_iter(fpath)#

Parse messages from JSF file as generator (memory efficient).

Yields messages one at a time instead of loading entire file into memory. Useful for processing large JSF files or streaming to HDF5.

Parameters:
fpathPath

Path to JSF binary file.

Yields:
JSFMessage

Next parsed message object.

Raises:
FileNotFoundError

If JSF file does not exist.

Examples

>>> for message in read_jsf_iter(Path("survey.jsf")):
...     print(type(message).__name__)
...     if isinstance(message, SonarDataMessage):
...         process_sonar(message)
sidescanpy.io.jsf.reader.get_messages_by_index(fpath, start_idx=0, end_idx=None)#

Retrieve JSF messages by index range (slicing).

Efficiently reads a specific range of messages from JSF file without loading entire file. Useful for debugging or inspecting specific regions.

Parameters:
fpathPath

Path to JSF binary file.

start_idxint

Starting message index (0-indexed). Default: 0

end_idxint, optional

Ending message index (exclusive). If None, read to end of file.

Returns:
list[JSFMessage]

Messages in the specified range.

Examples

>>> # Get messages 100-150
>>> messages = get_messages_by_index(Path("survey.jsf"), 100, 150)
>>> # Get first 50 messages
>>> messages = get_messages_by_index(Path("survey.jsf"), 0, 50)
sidescanpy.io.jsf.reader.filter_messages_by_type(messages, message_type)#

Filter messages by type name.

Parameters:
messageslist[JSFMessage]

Input messages.

message_typestr

Message type name (e.g., ‘SonarDataMessage’, ‘PitchRollDataMessage’).

Returns:
list[JSFMessage]

Filtered messages matching the type.

Examples

>>> sonar_msgs = filter_messages_by_type(messages, 'SonarDataMessage')
>>> pitch_msgs = filter_messages_by_type(messages, 'PitchRollDataMessage')
sidescanpy.io.jsf.reader.filter_messages_by_frequency(messages, freq_hz)#

Filter SonarDataMessages by transmit frequency.

Parameters:
messageslist[SonarDataMessage]

Input sonar messages.

freq_hzint

Frequency in Hz to filter by.

Returns:
list[SonarDataMessage]

Messages matching the frequency.

Examples

>>> sonar_msgs = filter_messages_by_type(messages, 'SonarDataMessage')
>>> freq_1495 = filter_messages_by_frequency(sonar_msgs, 1495000)
sidescanpy.io.jsf.reader.get_message_statistics(messages)#

Get statistics about a collection of messages.

Parameters:
messageslist[JSFMessage]

Input messages.

Returns:
dict

Statistics including type breakdown, frequency distribution, etc.

Examples

>>> messages = read_jsf(Path("survey.jsf"))
>>> stats = get_message_statistics(messages)
>>> print(f"Total messages: {stats['total']}")
>>> print(f"By type: {stats['by_type']}")
sidescanpy.io.jsf.reader.export_messages_to_json(messages, output_path, pretty=True, max_messages=None)#

Export messages to JSON for inspection/debugging.

Creates a JSON file with all messages. Large numpy arrays are summarized to keep file size reasonable. Useful for inspecting message structure and debugging conversion issues.

Parameters:
messageslist[JSFMessage]

Messages to export.

output_pathPath

Output JSON file path.

prettybool

If True (default), use indentation for readability.

max_messagesint, optional

Maximum messages to export. If None, export all.

Examples

>>> messages = read_jsf(Path("survey.jsf"), N=100)
>>> export_messages_to_json(messages, Path("debug.json"))
>>> # Export only sonar messages
>>> sonar_msgs = filter_messages_by_type(messages, 'SonarDataMessage')
>>> export_messages_to_json(sonar_msgs, Path("sonar_debug.json"), max_messages=50)
sidescanpy.io.jsf.reader.export_messages_by_type_to_json(messages, output_dir)#

Export messages to separate JSON files organized by type.

Creates one JSON file per message type for easier inspection.

Parameters:
messageslist[JSFMessage]

Messages to export.

output_dirPath

Output directory for JSON files.

Examples

>>> messages = read_jsf(Path("survey.jsf"), N=1000)
>>> export_messages_by_type_to_json(messages, Path("debug_output"))
sidescanpy.io.jsf.reader.save_messages_to_pickle(messages, filepath)#

Save parsed messages to pickle file for caching during testing.

Allows caching parsed JSF messages to avoid re-parsing large files during repeated test runs.

Parameters:
messageslist[JSFMessage]

Messages to save.

filepathPath

Output pickle file path.

Examples

>>> messages = read_jsf(Path("survey.jsf"))
>>> save_messages_to_pickle(messages, Path("cached_messages.pkl"))
sidescanpy.io.jsf.reader.load_messages_from_pickle(filepath)#

Load parsed messages from pickle file.

Retrieves previously cached messages saved with save_messages_to_pickle().

Parameters:
filepathPath

Pickle file path to load.

Returns:
list[JSFMessage]

List of message objects.

Raises:
FileNotFoundError

If pickle file does not exist.

Examples

>>> messages = load_messages_from_pickle(Path("cached_messages.pkl"))