Integrate Bellhop Input Files with the bellhopModel Object
R2026bThis example shows how to import pre-existing Bellhop input files and build a fully configured bellhopModel object for acoustic simulation in MATLAB.
If you have a set of Bellhop text files (e.g. ENV, BTY, SSP, ATI, or BRC/TRC) from an existing workflow, this example lets you reuse that data directly. The workflow parses the ENV file, auto-detects which additional files are needed, reads them, and applies all parameters to a bellhopModel object.
Prerequisites
The bellhopModel object requires the path to the Bellhop executable to be set in MATLAB the first time it is used. The bellhopConfiguration function manages the path. Set setExecutablePath to true and select the executable path, if it is not already set.
setExecutablePath =false; if setExecutablePath executablePath =
"C:\Users\Username\bellhopEXE\bellhop.exe"; %#ok bellhopConfiguration("ExecutablePath",executablePath); end
Specify Input File Paths
Set the path to your Bellhop ENV file. The example detects which companion files are needed from the ENV contents and reads them automatically.
If you do not have your own files, check useSampleFiles to generate example files in a temporary directory.
useSampleFiles =true; if useSampleFiles envFile = createSampleENVFile(); btyFile = createSampleBTYFile(); brcFile = createSampleBRCFile(); sspFile = createSampleSSPFile(); atiFile = ""; trcFile = ""; else envFile =
"path\to\your\bellhop.env"; %#ok btyFile =
""; atiFile =
""; brcFile =
""; trcFile =
""; sspFile =
""; end
Parse the ENV File
The helperReadENVFile function parses all blocks of a standard Bellhop ENV file and returns a struct whose fields map directly to bellhopModel properties. It also reports logical flags indicating which companion files the ENV expects.
env = helperReadENVFile(envFile)
env = struct with fields:
Title: "Munk profile"
Frequency: 50
TopOption: "QVWT"
SSPInterpolationMethod: "quadrilateral"
SeawaterAttenuation: "thorp"
SurfaceAltimetryFile: 0
SoundSpeedDepth: [10×1 double]
SoundSpeed: [10×1 double]
BottomOption: 'F~'
BottomReflectionCoefficientFile: 1
BottomBathymetryFile: 1
SourceDepths: 1000
ReceiverDepths: 800
ReceiverRanges: 100000
RunType: 'A'
BeamType: "geometric-hat"
NumRays: "auto"
RayElevationAngles: [-20 20]
StepSize: "auto"
RayTraceDepthLimit: 5500
RayTraceRangeLimit: 101000
SurfaceReflectionCoefficientFile: 0
Detect Additional Required Files
The ENV struct contains flags that indicate which additional input files Bellhop expects. Check each flag and validates that a file path was provided.
needsBTY = env.BottomBathymetryFile; needsATI = env.SurfaceAltimetryFile; needsBRC = env.BottomReflectionCoefficientFile; needsTRC = env.SurfaceReflectionCoefficientFile; needsSSP = (env.SSPInterpolationMethod == "quadrilateral"); if needsBTY && strlength(btyFile) == 0 warning("ENV file indicates a BTY file is required. Specify btyFile path."); end if needsATI && strlength(atiFile) == 0 warning("ENV file indicates an ATI file is required. Specify atiFile path."); end if needsBRC && strlength(brcFile) == 0 warning("ENV file indicates a BRC file is required. Specify brcFile path."); end if needsTRC && strlength(trcFile) == 0 warning("ENV file indicates a TRC file is required. Specify trcFile path."); end if needsSSP && strlength(sspFile) == 0 warning("ENV file uses quadrilateral SSP interpolationis required. Specify sspFile path."); end companionFiles = table( ... ["BTY"; "ATI"; "BRC"; "TRC"; "SSP"], ... ["Bathymetry"; "Altimetry"; "Bottom Reflection Coefficient"; "Surface Reflection Coefficient"; "Range-Dependent SSP"], ... [needsBTY; needsATI; needsBRC; needsTRC; needsSSP], ... VariableNames=["FileType", "Description", "Required"]); disp(companionFiles)
FileType Description Required
________ ________________________________ ________
"BTY" "Bathymetry" true
"ATI" "Altimetry" false
"BRC" "Bottom Reflection Coefficient" true
"TRC" "Surface Reflection Coefficient" false
"SSP" "Range-Dependent SSP" true
Read Additional Input Files
Read each input file that was detected as required and has a valid path.
if needsBTY && strlength(btyFile) > 0 [btyData, btyInterp] = helperReadBTYFile(btyFile); bathymetry = table(btyData(:,1), btyData(:,2), ... VariableNames=["Range_m", "Depth_m"]) end
bathymetry = 6×2 table
Range_m Depth_m
________ _______
0 5000
25000 5000
50000 3000
75000 5000
1.01e+05 5000
1.1e+05 5000
if needsATI && strlength(atiFile) > 0 [atiData, atiInterp] = helperReadBTYFile(atiFile); altimetry = table(atiData(:,1), atiData(:,2), ... VariableNames=["Range_m", "Height_m"]) end if needsBRC && strlength(brcFile) > 0 brcData = helperReadRCFile(brcFile); bottomReflectionCoefficients = table(brcData(:,1), abs(brcData(:,2)), rad2deg(angle(brcData(:,2))), ... VariableNames=["GrazingAngle_deg", "Magnitude", "Phase_deg"]) end
bottomReflectionCoefficients = 5×3 table
GrazingAngle_deg Magnitude Phase_deg
________________ _________ _________
0 0.98 175
15 0.85 160
30 0.6 140
60 0.35 120
90 0.2 100
if needsTRC && strlength(trcFile) > 0 trcData = helperReadRCFile(trcFile); surfaceReflectionCoefficients = table(trcData(:,1), abs(trcData(:,2)), rad2deg(angle(trcData(:,2))), ... VariableNames=["GrazingAngle_deg", "Magnitude", "Phase_deg"]) end if needsSSP && strlength(sspFile) > 0 [sspRanges, sspMatrix] = helperReadSSPFile(sspFile); rangeDependentSSP = array2table(sspMatrix, ... VariableNames="Range_" + string(sspRanges) + "_m"); rangeDependentSSP = addvars(rangeDependentSSP, env.SoundSpeedDepth, Before=1, NewVariableNames="Depth_m") end
rangeDependentSSP = 10×5 table
Depth_m Range_0_m Range_35000_m Range_70000_m Range_110000_m
_______ _________ _____________ _____________ ______________
0 1548.5 1548.5 1548.5 1548.5
500 1517.8 1519.8 1521.8 1525.8
1000 1501.4 1501.4 1501.4 1501.4
1500 1500.1 1499.5 1499 1498
2000 1504.6 1504.6 1504.6 1504.6
2500 1511.1 1511.1 1511.1 1511.1
3000 1518.7 1518.7 1518.7 1518.7
3500 1526.7 1526.7 1526.7 1526.7
4000 1535 1535 1535 1535
5000 1551.9 1551.9 1551.9 1551.9
Configure the bellhopModel Object
Create a single bellhopModel and apply all data from the ENV file and companion files.
bm = bellhopModel( ... SoundSpeedDepth=env.SoundSpeedDepth, ... SSPInterpolationMethod=env.SSPInterpolationMethod, ... RayElevationAngles=env.RayElevationAngles, ... NumRays=env.NumRays, ... BeamType=env.BeamType, ... SeawaterAttenuation=env.SeawaterAttenuation, ... StepSize=env.StepSize, ... RayTraceDepthLimit=env.RayTraceDepthLimit, ... RayTraceRangeLimit=env.RayTraceRangeLimit); % Sound speed profile if needsSSP bm.SoundSpeed = sspMatrix; bm.SoundSpeedRange = sspRanges; else bm.SoundSpeed=env.SoundSpeed; end % Francois-Garrison attenuation parameters if env.SeawaterAttenuation == "francois-garrison" bm.EffectiveTemperature = env.EffectiveTemperature; bm.EffectiveSalinity = env.EffectiveSalinity; bm.EffectiveAcidity = env.EffectiveAcidity; bm.EffectiveDepth = env.EffectiveDepth; end % Bathymetry if needsBTY bm.BottomBathymetryProfile = btyData; bm.BathymetryInterpolationMethod = btyInterp; end % Altimetry if needsATI bm.SurfaceAltimetryProfile = atiData; bm.AltimetryInterpolationMethod = atiInterp; end % Bottom reflection coefficients if needsBRC bm.BottomReflectionCoefficients = brcData; end % Surface reflection coefficients if needsTRC bm.SurfaceReflectionCoefficients = trcData; end disp(bm)
bellhopModel handle with properties:
SoundSpeed: [10×4 double]
SoundSpeedDepth: [10×1 double]
SoundSpeedRange: [0 35000 70000 110000]
SSPInterpolationMethod: "quadrilateral"
BottomBathymetryProfile: [6×2 double]
BottomReflectionCoefficients: [5×2 double]
BathymetryInterpolationMethod: "linear"
SurfaceAltimetryProfile: "flat"
SurfaceReflectionCoefficients: -1
Show all properties
Calculate Propagation Paths
Use the propagationPaths function of bellhopModel object to compute propagation paths between a source and receiver. Specify source and receiver positions as a [x; y; z] column vectors in meters.
fc = env.Frequency; srcDepth = env.SourceDepths; srcLocation = [0; 0; srcDepth]; rxRange = env.ReceiverRanges; rxDepth = env.ReceiverDepths; rxLocation = [rxRange; 0; rxDepth]; paths = propagationPaths(bm,fc,srcLocation,rxLocation)
paths = 29×7 table
PathLoss PathDelay PhaseShift AngleOfDeparture AngleOfArrival NumSurfaceReflections NumBottomReflections
________ _________ __________ ________________ ______________ _____________________ ____________________
86.438 66.628 0 0 -6.3396 0 0.38658 0 0
91.364 66.627 -90 0 -6.8891 0 -2.9833 0 0
95.066 66.567 180 0 9.8433 0 -7.7065 0 0
95.486 66.586 -90 0 8.1294 0 5.3193 0 0
107.82 69.371 91.561 0 18.972 0 -17.718 3 4
107.86 66.903 -110.43 0 -12.192 0 -14.29 1 2
108.37 67.04 -25.035 0 -13.033 0 11.624 1 2
108.49 69.754 -94.438 0 -19.693 0 -18.771 4 4
108.52 69.658 -93.315 0 19.855 0 18.541 4 4
110.09 66.822 -109.9 0 15.475 0 9.568 1 2
110.68 66.909 -110.61 0 -12.593 0 -11.894 1 2
110.86 70.131 75.856 0 -16.195 0 21.275 5 4
111.28 66.719 162.8 0 15.075 0 -12.947 1 2
113.18 66.83 -110.44 0 14.194 0 12.456 1 2
113.31 66.72 163.15 0 15.035 0 -14.625 1 2
114.46 66.713 163.62 0 15.235 0 -13.963 1 2
⋮
Plot the computed eigenrays by calling propagationPaths function with no output arguments.
propagationPaths(bm,fc,srcLocation,rxLocation)

Transmission Loss
Compute and visualize the incoherent transmission loss over the full range-depth grid. When RayTraceRangeLimit is set and no receiver location is specified, transmissionLoss function computes the transmission loss over the entire domain.
transmissionLoss(bm, fc, srcLocation);

Helper Functions
helperReadENVFile.m
helperReadBTYFile.m
helperReadRCFile.m
helperReadSSPFile.m
Local Functions
The helper functions below generate sample Bellhop input files. They write temporary files that exercise bathymetry (BTY), bottom reflection coefficients (BRC), and range-dependent sound speed (SSP) input files.
function envFile = createSampleENVFile() %createSampleENVFile Create a sample ENV file that triggers BTY, BRC, and SSP reading. envFile = fullfile(pwd, 'bellhopSampleMunk.env'); fid = fopen(envFile, 'w'); fprintf(fid, "'Munk profile'\n"); fprintf(fid, "50.0\n"); fprintf(fid, "1\n"); fprintf(fid, "'QVWT'\n"); fprintf(fid, "0 0.0 5000.0\n"); fprintf(fid, "0.0 1548.52 /\n"); fprintf(fid, "500.0 1517.78 /\n"); fprintf(fid, "1000.0 1501.38 /\n"); fprintf(fid, "1500.0 1500.12 /\n"); fprintf(fid, "2000.0 1504.62 /\n"); fprintf(fid, "2500.0 1511.12 /\n"); fprintf(fid, "3000.0 1518.67 /\n"); fprintf(fid, "3500.0 1526.74 /\n"); fprintf(fid, "4000.0 1535.04 /\n"); fprintf(fid, "5000.0 1551.91 /\n"); fprintf(fid, "'F~' 0.0\n"); fprintf(fid, "1\n"); fprintf(fid, "1000.0 /\n"); fprintf(fid, "1\n"); fprintf(fid, "800.0 /\n"); fprintf(fid, "1\n"); fprintf(fid, "100.0 /\n"); fprintf(fid, "'AGOR'\n"); fprintf(fid, "0\n"); fprintf(fid, "-20.0 20.0 /\n"); fprintf(fid, "0.0 5500.0 101.0\n"); fclose(fid); end function btyFile = createSampleBTYFile() %createSampleBTYFile Create a sample BTY file with a seamount. btyFile = fullfile(pwd, 'demo_seamount.bty'); fid = fopen(btyFile, 'w'); fprintf(fid, "'LS'\n"); fprintf(fid, "6\n"); fprintf(fid, "0.0 5000\n"); fprintf(fid, "25.0 5000\n"); fprintf(fid, "50.0 3000\n"); fprintf(fid, "75.0 5000\n"); fprintf(fid, "101.0 5000\n"); fprintf(fid, "110.0 5000\n"); fclose(fid); end function brcFile = createSampleBRCFile() %createSampleBRCFile Create a sample BRC file (sandy bottom). brcFile = fullfile(pwd, 'demo_bottom.brc'); fid = fopen(brcFile, 'w'); fprintf(fid, "5\n"); fprintf(fid, "0.0 0.98 175.0\n"); fprintf(fid, "15.0 0.85 160.0\n"); fprintf(fid, "30.0 0.60 140.0\n"); fprintf(fid, "60.0 0.35 120.0\n"); fprintf(fid, "90.0 0.20 100.0\n"); fclose(fid); end function sspFile = createSampleSSPFile() %createSampleSSPFile Create a sample range-dependent SSP file. sspFile = fullfile(pwd, 'demo_rangedep.ssp'); fid = fopen(sspFile, 'w'); fprintf(fid, "4\n"); fprintf(fid, "0.0 35.0 70.0 110.0\n"); fprintf(fid, "1548.52 1548.52 1548.52 1548.52\n"); fprintf(fid, "1517.78 1519.78 1521.78 1525.78\n"); fprintf(fid, "1501.38 1501.38 1501.38 1501.38\n"); fprintf(fid, "1500.12 1499.50 1499.00 1498.00\n"); fprintf(fid, "1504.62 1504.62 1504.62 1504.62\n"); fprintf(fid, "1511.12 1511.12 1511.12 1511.12\n"); fprintf(fid, "1518.67 1518.67 1518.67 1518.67\n"); fprintf(fid, "1526.74 1526.74 1526.74 1526.74\n"); fprintf(fid, "1535.04 1535.04 1535.04 1535.04\n"); fprintf(fid, "1551.91 1551.91 1551.91 1551.91\n"); fclose(fid); end








