Skip to content

Bellhop crash when using range-dependent SSP with scalar depth due to missing .bty file #116

@bpadovese

Description

@bpadovese

When using create_env2d() with a range-depth-dependent ssp and a constant scalar water depth, arlpy creates the environment successfully. However, a subsequent call to compute_transmission_loss() fails with the following Bellhop error:

[BELLHOP]  *** FATAL ERROR ***
[BELLHOP]  Generated by program or subroutine: READIN
[BELLHOP]  Unknown bottom option letter in second position

The above error can be reproduced directly using the range-dependent ssp example from the documentation:

import arlpy.uwapm as pm
import pandas as pd

ssp2 = pd.DataFrame({
    0: [1540, 1530, 1532, 1533],     # profile at 0 m range
    100: [1540, 1535, 1530, 1533],   # profile at 100 m range
    200: [1530, 1520, 1522, 1525]    # profile at 200 m range
}, index=[0, 10, 20, 30])            # depths of the profile entries in m

env = pm.create_env2d(depth=20, soundspeed=ssp2)
pm.compute_transmission_loss(env) # And then calling the tl function

While the error manifests during the transmission loss computation, the issue stems from how the .env file is written by arlpy and how Bellhop interprets it.

Internally, arlpy correctly detects the use of a range-dependent ssp and sets the ssp interpolation flag to 'Q'. It also correctly assumes a flat-bottom environment and sets the bathymetry option to just 'A' (constant depth) without a '*' and does not generate a .bty file.

Individually, both settings are valid. However, in combination, they lead to an edge case that Bellhop cannot handle: when the ssp is range-dependent, Bellhop expects a corresponding .bty file, even if the bottom is flat. Without it, Bellhop fails with the somewhat confusing error above. Bellhop's documentation seem to imply this as well. In the example below a flat bottom is implemented via a .bty file even when the depth is constant across range:

Image


The error can be avoided by explicitly providing a flat, range-dependent bathymetry:

depth = [[0, 20], [200., 20]]
env = pm.create_env2d(depth=depth, soundspeed=ssp2)

This causes arlpy to generate the .bty file and correctly set the bottom flag to 'A*', resolving the issue.

Sggested solutions:

  1. In my view, the main issue isn’t the edge case itself, but rather that the error message from Bellhop is uninformative. arlpy could proactively catch this configuration in check_env2d() or _create_env_file() and raise a clear validation error when a range-dependent ssp is provided alongside a scalar depth like so:
'Range-dependent soundspeed profile requires range-dependent bathymetry. Please provide `depth` as a Nx2 array (e.g., [[0, depth], ..., [max_range, depth]])'

And also addressing the example in the documentation.

  1. Automatically convert scalar depth to a flat range-dependent profile (e.g., [0, depth], [max_range, depth]) when soundspeed is range dependent as well.

Thanks for the package!

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions