All package functions¶
These are the functions exposed when use import bellhop as bh.
Underwater acoustic propagation modeling toolbox.
This toolbox uses the Bellhop acoustic propagation model. For this model to work, the complete bellhop.py package must be built and installed and bellhop.exe should be in your PATH.
- class bellhop.main.Any(*args, **kwargs)[source]¶
Special type indicating an unconstrained type.
Any is compatible with every type.
Any assumed to have all methods.
All values assumed to be instances of Any.
Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks.
- class bellhop.main.Defaults(model_name: str = 'bellhop', exe: str = 'bellhop.exe', beam_angle_halfspace: float = 90.0, beam_angle_fullspace: float = 180.0, env_comment_pad: int = 50, interference_mode: str = _Strings.coherent)[source]¶
Dataclass of hard-coded defaults used throughout the Bellhop interface.
- beam_angle_fullspace: float = 180.0¶
- beam_angle_halfspace: float = 90.0¶
- env_comment_pad: int = 50¶
- exe: str = 'bellhop.exe'¶
- interference_mode: str = 'coherent'¶
- model_name: str = 'bellhop'¶
- bellhop.main.read_env(fname: str) Environment [source]¶
Read a 2D underwater environment from a BELLHOP .env file.
This function parses a BELLHOP .env file and returns a Python data structure that is compatible with create_env(). This enables round-trip testing and compatibility between file-based and programmatic environment definitions.
- Parameters:
fname (str) – Path to .env file (with or without .env extension)
- Returns:
Environment dictionary compatible with create_env()
- Return type:
dict
Notes
Unit conversions performed:
Receiver ranges: km → m
Bottom density: g/cm³ → kg/m³
All other units preserved as in ENV file
Examples
>>> import bellhop as bh >>> env = bh.read_env('examples/Munk/MunkB_ray.env') >>> print(env['name']) 'Munk profile' >>> print(env['frequency']) 50.0
>>> # Use with existing functions >>> checked_env = bh.check_env(env) >>> rays = bh.compute_rays(env)
>>> # Round-trip compatibility >>> env_orig = bh.create_env(name="test", frequency=100) >>> # ... write to file via BELLHOP ... >>> env_read = bh.read_env("test.env") >>> assert env_read['frequency'] == env_orig['frequency']
- bellhop.main.read_ssp(fname: str, depths: List[float] | numpy.typing.NDArray.numpy.float64 | pandas.DataFrame | None = None) numpy.typing.NDArray.numpy.float64 | pandas.DataFrame [source]¶
Read a 2D sound speed profile (.ssp) file used by BELLHOP.
This function reads BELLHOP’s .ssp files which contain range-dependent sound speed profiles. The file format is: - Line 1: Number of range profiles (NPROFILES) - Line 2: Range coordinates in km (space-separated) - Line 3+: Sound speed values, one line per depth point across all ranges
- Parameters:
fname (str) – Path to .ssp file (with or without .ssp extension)
- Returns:
For single-profile files: numpy array with [depth, soundspeed] pairs; for multi-profile files: pandas DataFrame with range-dependent sound speed data
- Return type:
numpy.ndarray or pandas.DataFrame
Notes
Return format:
Single-profile files (1 range): Returns a 2D numpy array with [depth, soundspeed] pairs, compatible with create_env() soundspeed parameter.
Multi-profile files (>1 ranges): Returns a pandas DataFrame where:
Columns: Range coordinates (in meters, converted from km in file)
Index: Depth indices (0, 1, 2, … for each depth level in the file)
Values: Sound speeds (m/s)
This DataFrame can be directly assigned to create_env() soundspeed parameter for range-dependent acoustic modeling.
Note on depths: For multi-profile files, depth indices are used (0, 1, 2, …) since the actual depth coordinates come from the associated BELLHOP .env file. Users can modify the DataFrame index if actual depth values are known.
Examples
>>> import bellhop as bh >>> # Single-profile file >>> ssp1 = bh.read_ssp("single_profile.ssp") # Returns numpy array >>> env = bh.create_env() >>> env["soundspeed"] = ssp1 >>> >>> # Multi-profile file >>> ssp2 = bh.read_ssp("tests/MunkB_geo_rot/MunkB_geo_rot.ssp") # Returns DataFrame >>> env = bh.create_env() >>> env["soundspeed"] = ssp2 # Range-dependent sound speed
File format example:
30 -50 -5 -1 -.8 -.75 -.6 -.4 -.2 0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 10.0 1500 1500 1548.52 1530.29 1526.69 1517.78 1509.49 1504.30 1501.38 1500.14 1500.12 1501.02 1502.57 1504.62 1507.02 1509.69 1512.55 1515.56 1518.67 1521.85 1525.10 1528.38 1531.70 1535.04 1538.39 1541.76 1545.14 1548.52 1551.91 1551.91 1500 1500 1548.52 1530.29 1526.69 1517.78 1509.49 1504.30 1501.38 1500.14 1500.12 1501.02 1502.57 1504.62 1507.02 1509.69 1512.55 1515.56 1518.67 1521.85 1525.10 1528.38 1531.70 1535.04 1538.39 1541.76 1545.14 1548.52 1551.91 1551.91
- bellhop.main.read_ati(fname: str) Tuple[numpy.typing.NDArray.numpy.float64, str] [source]¶
Read an altimetry file used by Bellhop.
- bellhop.main.read_bty(fname: str) Tuple[numpy.typing.NDArray.numpy.float64, str] [source]¶
Read a bathymetry file used by Bellhop.
- bellhop.main.read_sbp(fname: str) numpy.typing.NDArray.numpy.float64 [source]¶
Read an source beam patterm (.sbp) file used by BELLHOP.
The file format is: - Line 1: Number of points - Line 2+: Angle (deg) and power (dB) pairs
- Parameters:
fname (str) – Path to .sbp file (with or without extension)
- Returns:
Numpy array with [angle, power] pairs
- Return type:
numpy.ndarray
- bellhop.main.read_trc(fname: str) numpy.typing.NDArray.numpy.float64 [source]¶
Read a TRC file and return array of reflection coefficients.
See read_refl_coeff for documentation, but use this function for extension checkking.
- bellhop.main.read_brc(fname: str) numpy.typing.NDArray.numpy.float64 [source]¶
Read a BRC file and return array of reflection coefficients.
See read_refl_coeff for documentation, but use this function for extension checkking.
- bellhop.main.read_shd(fname: str) pandas.DataFrame [source]¶
Read Bellhop shd file and parse data into a high level data structure
- bellhop.main.read_rays(fname: str) pandas.DataFrame [source]¶
Read Bellhop rays file and parse data into a high level data structure
- bellhop.main.read_arrivals(fname: str) pandas.DataFrame [source]¶
Read Bellhop arrivals file and parse data into a high level data structure
- class bellhop.main.Environment(name: str = 'bellhop/python default', type: str = '2D', frequency: float = 25000.0, _num_media: int = 1, soundspeed: float | Any = 1500.0, soundspeed_interp: str = _Strings.linear, depth: float | Any = 25.0, depth_interp: str = _Strings.linear, _mesh_npts: int = 0, _depth_sigma: float = 0.0, depth_max: float | None = None, _bathymetry: str = _Strings.flat, _altimetry: str = _Strings.flat, _sbp_file: str = _Strings.default, bottom_interp: str | None = None, bottom_soundspeed: float = 1600.0, _bottom_soundspeed_shear: float = 0.0, bottom_density: float = 1600, bottom_attenuation: float | None = None, _bottom_attenuation_shear: float | None = None, bottom_roughness: float = 0.0, bottom_beta: float | None = None, bottom_transition_freq: float | None = None, bottom_boundary_condition: str = _Strings.acousto_elastic, bottom_reflection_coefficient: Any | None = None, surface: Any | None = None, surface_interp: str = _Strings.linear, surface_boundary_condition: str = _Strings.vacuum, surface_reflection_coefficient: Any | None = None, surface_depth: float = 0.0, surface_soundspeed: float = 1600.0, _surface_soundspeed_shear: float = 0.0, surface_density: float = 1000.0, surface_attenuation: float | None = None, _surface_attenuation_shear: float | None = None, source_type: str = 'default', source_depth: float | Any = 5.0, source_ndepth: int | None = None, source_directionality: Any | None = None, receiver_depth: float | Any = 10.0, receiver_range: float | Any = 1000.0, receiver_ndepth: int | None = None, receiver_nrange: int | None = None, beam_type: str = _Strings.default, beam_angle_min: float | None = None, beam_angle_max: float | None = None, beam_num: int = 0, single_beam_index: int | None = None, _single_beam: str = _Strings.default, step_size: float | None = 0.0, box_depth: float | None = None, box_range: float | None = None, grid_type: str = 'default', task: str | None = None, interference_mode: str | None = None, volume_attenuation: str = 'none', attenuation_units: str = 'frequency dependent', fg_salinity: float | None = None, fg_temperature: float | None = None, fg_pH: float | None = None, fg_depth: float | None = None)[source]¶
Dataclass for underwater acoustic environment configuration.
This class provides automatic validation of environment parameters, eliminating the need for manual checking of option validity.
These entries are either intended to be set or edited by the user, or with _ prefix are internal state read from a .env file or inferred by other data. Some others are ignored.
- _abc_impl = <_abc._abc_data object>¶
- _altimetry: str = 'flat'¶
- _bathymetry: str = 'flat'¶
- _bottom_attenuation_shear: float | None = None¶
- _bottom_soundspeed_shear: float = 0.0¶
- _depth_sigma: float = 0.0¶
- _finalise() Environment [source]¶
Reviews the data within an environment and updates settings for consistency.
This function is run as the first step of check_env().
- _mesh_npts: int = 0¶
- _num_media: int = 1¶
- _sbp_file: str = 'default'¶
- _single_beam: str = 'default'¶
- _surface_attenuation_shear: float | None = None¶
- _surface_soundspeed_shear: float = 0.0¶
- attenuation_units: str = 'frequency dependent'¶
- beam_angle_max: float | None = None¶
- beam_angle_min: float | None = None¶
- beam_num: int = 0¶
- beam_type: str = 'default'¶
- bottom_attenuation: float | None = None¶
- bottom_beta: float | None = None¶
- bottom_boundary_condition: str = 'acousto-elastic'¶
- bottom_density: float = 1600¶
- bottom_interp: str | None = None¶
- bottom_roughness: float = 0.0¶
- bottom_soundspeed: float = 1600.0¶
- bottom_transition_freq: float | None = None¶
- box_depth: float | None = None¶
- box_range: float | None = None¶
- check() Environment [source]¶
- copy() Environment [source]¶
Return a shallow copy of the environment.
- depth_interp: str = 'linear'¶
- depth_max: float | None = None¶
- fg_depth: float | None = None¶
- fg_pH: float | None = None¶
- fg_salinity: float | None = None¶
- fg_temperature: float | None = None¶
- frequency: float = 25000.0¶
- grid_type: str = 'default'¶
- interference_mode: str | None = None¶
- name: str = 'bellhop/python default'¶
- receiver_ndepth: int | None = None¶
- receiver_nrange: int | None = None¶
- single_beam_index: int | None = None¶
- soundspeed_interp: str = 'linear'¶
- source_ndepth: int | None = None¶
- source_type: str = 'default'¶
- step_size: float | None = 0.0¶
- surface_attenuation: float | None = None¶
- surface_boundary_condition: str = 'vacuum'¶
- surface_density: float = 1000.0¶
- surface_depth: float = 0.0¶
- surface_interp: str = 'linear'¶
- surface_soundspeed: float = 1600.0¶
- task: str | None = None¶
- type: str = '2D'¶
- volume_attenuation: str = 'none'¶
- class bellhop.main.Bellhop(name: str = 'bellhop', exe: str = 'bellhop.exe', env_comment_pad: int = 50)[source]¶
Interface to the Bellhop 2D underwater acoustics ray tracing propagation model.
Two public methods are defined: supports() and run(). Both take arguments of environment and task, and respectively report whether the executable can perform the task, and to do so.
- Parameters:
name (str) – User-fancing name for the model
exe (str) – Filename of Bellhop executable
- _array2str(values: List[Any]) str [source]¶
Format list into space-separated string, trimmed at first None, ending with ‘/’.
- _create_env_file(env: Environment, taskcode: str, fh: TextIO, fname_base: str) None [source]¶
Writes a complete .env file for specifying a Bellhop simulation
- Parameters:
env (dict) – Environment dict
taskcode (str) – Task string which defines the computation to run
fh (file object) – File reference (already opened)
fname_base (str) – Filename base (without extension)
:param : :type : returns fname_base: filename base (no extension) of written file :param We liberally insert comments and empty lines for readability and take care to: :param ensure that comments are consistently aligned.: :param This doesn’t make a difference to bellhop.exe: :param it just makes debugging far easier.:
- _create_ssp_quad_file(filename: str, svp: pandas.DataFrame) None [source]¶
Write 2D SSP data to file
- _prepare_env_file(fname_base: str | None) Tuple[int, str] [source]¶
Opens a file for writing the .env file, in a temp location if necessary, and delete other files with same basename.
- Parameters:
fname_base (str, optional) – Filename base (no extension) for writing – if not specified a temporary file (and location) will be used instead
- Returns:
fh (int) – File descriptor
fname_base (str) – Filename base
- _print(fh: TextIO, s: str, newline: bool = True) None [source]¶
Write a line of text with or w/o a newline char to the output file
- _print_array(fh: TextIO, a: Any, label: str = '', nn: int | None = None) None [source]¶
Print a 1D array to the .env file, prefixed by a count of the array length
- _print_env_line(fh: TextIO, data: Any, comment: str = '') None [source]¶
Write a complete line to the .env file with a descriptive comment
We do some char counting (well, padding and stripping) to ensure the code comments all start from the same char.
- _quoted_opt(*args: str) str [source]¶
Concatenate N input _Strings. strip whitespace, surround with single quotes
- _rm_files(fname_base: str, not_env: bool = False) None [source]¶
Remove files that would be constructed as bellhop inputs or created as bellhop outputs.
- _run_exe(fname_base: str, args: str = '', debug: bool = False, exe: str | None = None) None [source]¶
Run the executable and raise exceptions if there are errors.
Writes beam and footer lines of env file.
- _write_env_bottom(fh: TextIO, env: Environment) None [source]¶
Writes bottom boundary lines of env file.
- _write_env_header(fh: TextIO, env: Environment) None [source]¶
Writes header of env file.
- _write_env_sound_speed(fh: TextIO, env: Environment) None [source]¶
Writes sound speed profile lines of env file.
- _write_env_source_receiver(fh: TextIO, env: Environment) None [source]¶
Writes source and receiver lines of env file.
- _write_env_surface_depth(fh: TextIO, env: Environment) None [source]¶
Writes surface boundary and depth lines of env file.
- _write_env_task(fh: TextIO, env: Environment, taskcode: str) None [source]¶
Writes task lines of env file.
- run(env: Environment, task: str, debug: bool = False, fname_base: str | None = None) Any [source]¶
High-level interface function which runs the model.
The function definition performs setup and cleanup tasks and passes the execution off to an auxiliary function.
Uses the taskmap data structure to relate input flags to processng stages, in particular how to select specific “tasks” to be executed.
- supports(env: Environment | None = None, task: str | None = None, exe: str | None = None) bool [source]¶
Check whether the model supports the task.
This function is supposed to diagnose whether this combination of environment and task is supported by the model.
- bellhop.main.new_model(name: str, **kwargs: Any) Bellhop [source]¶
Instantiate a new Bellhop model and add it to the list of models.
Creates a Bellhop instance with the specified parameters and adds it to the internal registry of models for later access.
- Parameters:
name (str) – Descriptive name for this model instance, must be unique
**kwargs –
Keyword arguments passed directly to the Bellhop constructor. Common parameters include: - exe : str
Filename of the Bellhop executable
- Returns:
The newly created Bellhop model instance.
- Return type:
Examples
>>> bh.models() # there is always a default model ['bellhop'] >>> bh.new_model(name="bellhop-at", exe="bellhop_at.exe") >>> bh.models() ['bellhop', 'bellhop-at']
- bellhop.main.models(env: Environment | None = None, task: str | None = None) List[str] [source]¶
List available models.
- Parameters:
env (dict, optional) – Environment to model
task (str, optional) – Task type: arrivals/eigenrays/rays/coherent/incoherent/semicoherent
- Returns:
List of models that can be used
- Return type:
list of str
Examples
>>> import bellhop as bh >>> bh.models() ['bellhop'] >>> env = bh.create_env() >>> bh.models(env, task="coherent") ['bellhop']
- bellhop.main.create_env2d(**kv: Any) Environment [source]¶
Backwards compatibility for create_env
- bellhop.main.create_env(**kv: Any) Environment [source]¶
Create a new underwater environment.
- Parameters:
**kv (dict) – Keyword arguments for environment configuration.
- Returns:
env – A new underwater environment dictionary.
- Return type:
dict
- Raises:
ValueError – If any parameter value is invalid according to BELLHOP constraints.
Example
To see all the parameters available and their default values:
>>> import bellhop as bh >>> env = bh.create_env() >>> print(env)
The environment parameters may be changed by passing keyword arguments or modified later using dictionary notation:
>>> import bellhop as bh >>> env = bh.create_env(depth=40, soundspeed=1540) >>> print(env) >>> env['depth'] = 25 >>> env['bottom_soundspeed'] = 1800 >>> print(env)
The default environment has a constant sound speed. A depth dependent sound speed profile be provided as a Nx2 array of (depth, sound speed):
>>> import bellhop as bh >>> env = bh.create_env(depth=20, >>>. soundspeed=[[0,1540], [5,1535], [10,1535], [20,1530]])
A range-and-depth dependent sound speed profile can be provided as a Pandas frame:
>>> import bellhop as bh >>> 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 = bh.create_env(depth=20, soundspeed=ssp2)
The default environment has a constant water depth. A range dependent bathymetry can be provided as a Nx2 array of (range, water depth):
>>> import bellhop as bh >>> env = bh.create_env(depth=[[0,20], [300,10], [500,18], [1000,15]])
- bellhop.main.check_env(env: Environment) Environment [source]¶
Check the validity of a underwater environment definition.
This function is automatically executed before any of the compute_ functions, but must be called manually after setting environment parameters if you need to query against defaults that may be affected.
- Parameters:
env (dict) – Environment definition
- Returns:
Updated environment definition
- Return type:
dict
- Raises:
ValueError – If the environment is invalid
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> env = check_env(env)
- bellhop.main.check_env2d(env: Environment) Environment [source]¶
Backwards compatibility for check_env
- bellhop.main.compute(env: Environment | List[Environment], model: Any | None = None, task: Any | None = None, debug: bool = False, fname_base: str | None = None) Any | Environment | Tuple[List[Environment], pandas.DataFrame] [source]¶
Compute Bellhop task(s) for given model(s) and environment(s).
- Parameters:
env (dict or list of dict) – Environment definition (which includes the task specification)
model (str, optional) – Propagation model to use (None to auto-select)
task (str or list of str, optional) – Optional task or list of tasks (“arrivals”, etc.)
debug (bool, default=False) – Generate debug information for propagation model
fname_base (str, optional) – Base file name for Bellhop working files, default (None), creates a temporary file
- Returns:
dict – Single run result (and associated metadata) if only one computation is performed.
tuple of (list of dict, pandas.DataFrame) – List of results and an index DataFrame if multiple computations are performed.
Notes
If any of env, model, and/or task are lists then multiple runs are performed with a list of dictionary outputs returned. The ordering is based on loop iteration but might not be deterministic; use the index DataFrame to extract and filter the output logically.
Examples
Single task based on reading a complete .env file: >>> import bellhop as bh >>> env = bh.read_env(”…”) >>> output = bh.compute(env) >>> assert output[‘task’] == “arrivals” >>> bh.plot_arrivals(output[‘results’])
Multiple tasks: >>> import bellhop as bh >>> env = bh.create_env() >>> output, ind_df = bh.compute(env,task=[“arrivals”, “eigenrays”]) >>> bh.plot_arrivals(output[0][‘results’])
- bellhop.main.compute_arrivals(env: Environment, model: Any | None = None, debug: bool = False, fname_base: str | None = None) Any [source]¶
Compute arrivals between each transmitter and receiver.
- Parameters:
env (dict) – Environment definition
model (str, optional) – Propagation model to use (None to auto-select)
debug (bool, default=False) – Generate debug information for propagation model
fname_base (str, optional) – Base file name for Bellhop working files, default (None), creates a temporary file
- Returns:
Arrival times and coefficients for all transmitter-receiver combinations
- Return type:
pandas.DataFrame
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> arrivals = bh.compute_arrivals(env) >>> bh.plot_arrivals(arrivals)
- bellhop.main.compute_eigenrays(env: Environment, source_depth_ndx: int = 0, receiver_depth_ndx: int = 0, receiver_range_ndx: int = 0, model: Any | None = None, debug: bool = False, fname_base: str | None = None) Any [source]¶
Compute eigenrays between a given transmitter and receiver.
- Parameters:
env (dict) – Environment definition
source_depth_ndx (int, default=0) – Transmitter depth index
receiver_depth_ndx (int, default=0) – Receiver depth index
receiver_range_ndx (int, default=0) – Receiver range index
model (str, optional) – Propagation model to use (None to auto-select)
debug (bool, default=False) – Generate debug information for propagation model
fname_base (str, optional) – Base file name for Bellhop working files, default (None), creates a temporary file
- Returns:
Eigenrays paths
- Return type:
pandas.DataFrame
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> rays = bh.compute_eigenrays(env) >>> bh.plot_rays(rays, width=1000)
- bellhop.main.compute_rays(env: Environment, source_depth_ndx: int = 0, model: Any | None = None, debug: bool = False, fname_base: str | None = None) Any [source]¶
Compute rays from a given transmitter.
- Parameters:
env (dict) – Environment definition
source_depth_ndx (int, default=0) – Transmitter depth index
model (str, optional) – Propagation model to use (None to auto-select)
debug (bool, default=False) – Generate debug information for propagation model
fname_base (str, optional) – Base file name for Bellhop working files, default (None), creates a temporary file
- Returns:
Ray paths
- Return type:
pandas.DataFrame
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> rays = bh.compute_rays(env) >>> bh.plot_rays(rays, width=1000)
- bellhop.main.compute_transmission_loss(env: Environment, source_depth_ndx: int = 0, mode: str | None = None, model: Any | None = None, debug: bool = False, fname_base: str | None = None) Any [source]¶
Compute transmission loss from a given transmitter to all receviers.
- Parameters:
env (dict) – Environment definition
source_depth_ndx (int, default=0) – Transmitter depth index
mode (str, optional) – Coherent, incoherent or semicoherent
model (str, optional) – Propagation model to use (None to auto-select)
debug (bool, default=False) – Generate debug information for propagation model
fname_base (str, optional) – Base file name for Bellhop working files, default (None), creates a temporary file
- Returns:
Complex transmission loss at each receiver depth and range
- Return type:
numpy.ndarray
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> tloss = bh.compute_transmission_loss(env, mode=bh.incoherent) >>> bh.plot_transmission_loss(tloss, width=1000)
- bellhop.main.arrivals_to_impulse_response(arrivals: Any, fs: float, abs_time: bool = False) Any [source]¶
Convert arrival times and coefficients to an impulse response.
- Parameters:
arrivals (pandas.DataFrame) – Arrivals times (s) and coefficients
fs (float) – Sampling rate (Hz)
abs_time (bool, default=False) – Absolute time (True) or relative time (False)
- Returns:
Impulse response
- Return type:
numpy.ndarray
Notes
If abs_time is set to True, the impulse response is placed such that the zero time corresponds to the time of transmission of signal.
Examples
>>> import bellhop as bh >>> env = bh.create_env() >>> arrivals = bh.compute_arrivals(env) >>> ir = bh.arrivals_to_impulse_response(arrivals, fs=192000)