///|
/// Find the peak absolute amplitude in a seismic trace.
pub fn peak_amplitude(trace : Trace) -> Double {
let n = trace.npts()
if n == 0 {
return 0.0
}
let mut max_val = 0.0
for v in trace.data {
let abs_v = v.abs()
if abs_v > max_val {
max_val = abs_v
}
}
max_val
}
///|
/// Calculate Richter Local Magnitude (M_L).
/// * `peak_amp_mm` : The peak amplitude measured on a simulated Wood-Anderson seismograph in mm.
/// * `distance_km` : The epicentral distance in km.
pub fn local_magnitude(
peak_amp_mm : Double,
distance_km : Double,
) -> Result[Double, String] {
if distance_km <= 0.0 {
return Err("Distance must be positive")
}
if peak_amp_mm <= 0.0 {
return Err("Amplitude must be positive")
}
let log_a = @math.log10(peak_amp_mm)
// Standard Richter calibration function: -log10(A_0)
// Approximated for distances under 200 km
let calib = 1.11 * @math.log10(distance_km) + 0.00189 * distance_km - 2.09
Ok(log_a + calib)
}
///|
/// Calculate Body Wave Magnitude (M_b).
/// * `amplitude_micrometer` : Peak displacement amplitude in micrometers.
/// * `period_seconds` : Period of the wave in seconds.
/// * `distance_degrees` : Epicentral distance in degrees.
pub fn body_wave_magnitude(
amplitude_micrometer : Double,
period_seconds : Double,
distance_degrees : Double,
) -> Result[Double, String] {
if amplitude_micrometer <= 0.0 ||
period_seconds <= 0.0 ||
distance_degrees <= 0.0 {
return Err("All parameters must be positive")
}
let ratio = amplitude_micrometer / period_seconds
let log_at = @math.log10(ratio)
let calib = 3.75 + 1.2 * @math.log10(distance_degrees)
Ok(log_at + calib)
}
///|
/// Calculate Surface Wave Magnitude (M_s).
/// * `amplitude_micrometer` : Peak displacement amplitude in micrometers.
/// * `period_seconds` : Period of the wave in seconds.
/// * `distance_degrees` : Epicentral distance in degrees.
pub fn surface_wave_magnitude(
amplitude_micrometer : Double,
period_seconds : Double,
distance_degrees : Double,
) -> Result[Double, String] {
if amplitude_micrometer <= 0.0 ||
period_seconds <= 0.0 ||
distance_degrees <= 0.0 {
return Err("All parameters must be positive")
}
let ratio = amplitude_micrometer / period_seconds
let log_at = @math.log10(ratio)
let calib = 1.66 * @math.log10(distance_degrees) + 3.3
Ok(log_at + calib)
}