Introducing goneplax, a command line tool for inspecting Edgetech JSF files


I have just published a little command line tool called goneplax to help look at the JSF files that are output by Edgetech sonars. Imaging sonar data is an interesting problem because publicly accessible data usually is either georeferenced mosaics or raw instrument data. The former come in geospatial formats like GeoTIFFs but have lost a lot of information that I would like to have as I think about statistical models for imaging sonar data. The latter typically need proprietary software to access, and that software often locks you into particular kinds of data analysis like the production of georeferenced mosaics. There are some open source sonar data tools, notably MB-System from the Monterey Bay Aquarium Research Institute, but those aim to be fully featured data processing systems, whereas I am mostly interested in tools that allow me to build my own data analysis pipelines around sonar data.

However, my earlier attempt at this kind of tooling quickly ballooned out of control because there is a lot of stuff you can do with sonar data like format translation, visualization or even data analysis tools – I even briefly messed around with designing a programming language. I took a step back, thought about The Joy of Small Projects, and this morning came up with goneplax. I have a lot of JSF files sitting around (two particularly good sources for sonar data are PANGAEA and the UK government data portal), and the first step to using them for anything is to figure out what is in them. JSF files are basically sequences of records, each of which has a header that provides some information about the record. goneplax reads through these records, and writes out to the command line the type of each record, the subsystem it comes from and the channel within that subsystem (i.e. the port or starboard channels for sidescan data).

If we try it out on some data from Papenmeier and Hass (2019), we get something like

> goneplax HE501_Hydro1_001.jsf | head
System Information:0:0
Navigation Offsets:0:0
Pitch Roll Data:101:1
Pitch Roll Data:101:1
Sonar Data Message:20:0
Sonar Data Message:20:1
Pitch Roll Data:101:1
Unknown Message:102:0
Pitch Roll Data:101:1
Sonar Data Message:20:0

The first field is the type of the message, the second is the subsystem number and the third is the channel. For instance, in the first 10 records shown above, we have three Sonar Data Messages that contain sidescan data. These are all from subsystem 20, which is the code for the lowest available sidescan sonar frequency (these data only have one frequency). The first and the last are from the port side of the sonar (channel 0) and the second is from the starboard (channel 1).

goneplax outputs text data like this so we can use Unix command line tools to further process it. One common operation is to count the number of messages of each kind in a given file:

> goneplax HE501_Hydro1_001.jsf | sort | uniq -c
    1 Navigation Offsets:0:0
 9370 NMEA String:100:0
19440 Pitch Roll Data:101:1
 8721 Sonar Data Message:20:0
 8720 Sonar Data Message:20:1
    1 System Information:0:0
 1500 Unknown Message:102:0

which matches the output of jsfmesgtype, another command line tool that does something similar:

> jsfmesgtype HE501_Hydro1_001.jsf
Sonar = 17441  Pitch = 19440  NMEA = 9370  Analog = 1500  S_info = 1

If goneplax seems like it might be useful for you, give it a try and let me know how it goes at ~wkearn/

Lessons learned

  1. Completing a constrained project in a limited time span is a very good exercise. goneplax is not particularly useful, but it works. If I ever need to peek at a JSF file, I can just run goneplax <filename> from my terminal.
  2. I decided to host this project at Sourcehut rather than Github. I do like its minimalism compared to Github, though I have not had the opportunity to use its email-based patch workflow in earnest.
  3. This is written in Rust as opposed to Julia, which has been my preferred language for many years. I've been using Rust a lot over the last few months, and it is pretty well-suited to a tool like this.
  4. I tried to apply the ideas of matklad's Hard Mode Rust and the TigerBeetle developers' Tiger Style to goneplax. However, it just isn't all that complicated, so its allocation-free library just parses the JSF message headers. What little complexity there is in goneplax lies in the I/O, which is all handled using Rust's standard library. There are no dependencies beyond Rust's standard library.
  5. Goneplax rhomboides is a kind of crab.