public static string GetRadialConfiguration(AcousticProperties acousticProperties, SoundSpeedProfile ssp, SedimentType sediment, double maxDepth, double maxRadius, List<double> ranges, List<double> depths, bool useSurfaceReflection, bool useVerticalBeamforming, bool generateArrivalsFile, int beamCount) { using (var sw = new StringWriter()) { sw.WriteLine("'TL' ! Title"); sw.WriteLine("{0} ! Frequency (Hz)", acousticProperties.Frequency); sw.WriteLine("1 ! NMedia"); // was NMEDIA in gui_genbellhopenv.m sw.WriteLine(useSurfaceReflection ? "'CFFT ' ! Top Option" : "'CVFT ' ! Top Option"); sw.WriteLine("0 0.00 {0} ! N sigma depth", ssp.Data[ssp.Data.Count - 1].Depth); // If SSP is shallower than the bathymetry then extrapolate an SSP entry for the deepest part of the water //if (SSP.DepthVector[SSP.DepthVector.Length - 1] < RealBottomDepth_Meters) // SoundSpeedProfile = ExtrapolateSSP(SoundSpeedProfile, RealBottomDepth_Meters); foreach (var sample in ssp.Data) sw.WriteLine("{0:0.00} {1:0.00} 0.00 1.00 0.00 0.00 / ! z c cs rho", sample.Depth, sample.SoundSpeed); sw.WriteLine("'A*' 0.00 ! Bottom Option, sigma"); // A = Acoustic halfspace, ~ = read bathymetry file, 0.0 = bottom roughness (currently ignored) sw.WriteLine("{0} {1} {2} {3} {4} {5} / ! lower halfspace", maxDepth, sediment.CompressionWaveSpeed, sediment.ShearWaveSpeed, sediment.Density, sediment.LossParameter, 0); // Source and Receiver Depths and Ranges sw.WriteLine("1"); // Number of Source Depths sw.WriteLine("{0} /", acousticProperties.SourceDepth); // source depth sw.WriteLine("{0}", depths.Count); // Number of Receiver Depths foreach (var depth in depths) sw.Write("{0} ", depth); sw.WriteLine("/ ! Receiver Depths (m)"); sw.WriteLine("{0}", ranges.Count); // Number of Receiver Ranges foreach (var range in ranges) sw.Write("{0} ", range); sw.WriteLine("/ ! Receiver Ranges (km)"); if (generateArrivalsFile) sw.WriteLine("'aG'"); // aB else sw.WriteLine(useVerticalBeamforming ? "'IG*'" : "'I'"); // if useVerticalBeamforming is true, then SBPFIL must be present (Source Beam Pattern file) sw.WriteLine("{0}", beamCount); // Number of beams //sw.WriteLine("0"); // Number of beams var verticalHalfAngle = acousticProperties.VerticalBeamWidth / 2; var angle1 = acousticProperties.DepressionElevationAngle - verticalHalfAngle; var angle2 = acousticProperties.DepressionElevationAngle + verticalHalfAngle; sw.WriteLine("{0} {1} /", angle1, angle2); // Beam fan half-angles (negative angles are toward the surface //sw.WriteLine("-60.00 60.00 /"); // Beam fan half-angles (negative angles are toward the surface //sw.WriteLine("{0:F} {1:F} {2:F} ! step zbox(meters) rbox(km)", experiment.TransmissionLossSettings.DepthCellSize, RealBottomDepth_Meters + 100, (bottomProfile.Length / 1000.0) * 1.01); sw.WriteLine("{0} {1} {2}", (ranges[0] / 2) * 1000, maxDepth, maxRadius); return sw.ToString(); } }
public static void CreateBellhopEnvironment(string outputDirectory, string name, double sourceDepth, double frequency, double verticalBeamWidth, double depressionElevationAngle, List<double> bathymetryRanges, List<double> bathymetryDepths, List<double> soundspeedDepths, List<double> soundspeedSpeeds, List<double> receiverRanges, List<double> receiverDepths, int sedimentType, int beamCount, double maxDepth) { if (!Directory.Exists(outputDirectory)) Directory.CreateDirectory(outputDirectory); // Write the bathymetry file var bathymetryFilename = Path.Combine(outputDirectory, name + ".bty"); using (var writer = new StreamWriter(bathymetryFilename)) { writer.WriteLine("'C'"); writer.WriteLine(bathymetryRanges.Count); for (var index = 0; index < bathymetryRanges.Count; index++) writer.WriteLine("{0} {1}", bathymetryRanges[index], bathymetryDepths[index]); } var acousticProperties = new AcousticProperties { HighFrequency = (float)frequency, LowFrequency = (float)frequency, DepressionElevationAngle = (float)depressionElevationAngle, SourceDepth = (float)sourceDepth, VerticalBeamWidth = (float)verticalBeamWidth, }; var maxRadius = (int)Math.Ceiling(receiverRanges.Last() * 1.01); // Allow an extra 1% of range so the beams don't run off the end before they hit the last column of receivers var sspData = soundspeedDepths.Select((t, index) => new SoundSpeedSample((float)t, (float)soundspeedSpeeds[index])).ToList(); var soundSpeedProfile = new SoundSpeedProfile { Data = sspData }; var result = GetRadialConfiguration(acousticProperties, soundSpeedProfile, SedimentTypes.Find(sedimentType), maxDepth, maxRadius, receiverRanges, receiverDepths, false, true, true, beamCount); File.WriteAllText(Path.Combine(outputDirectory, name + ".env"), result, new ASCIIEncoding()); }