// Physical optical unit conversions and grid parameter checks.

///|
/// Convert power in Watts to dBm (decibel-milliwatts)
pub fn watts_to_dbm(power_w : Double) -> Double {
  if power_w <= 0.0 {
    -1000.0
  } else {
    10.0 * @math.log10(power_w * 1000.0)
  }
}

///|
/// Convert power in dBm to Watts
pub fn dbm_to_watts(power_dbm : Double) -> Double {
  @math.pow(10.0, power_dbm / 10.0) / 1000.0
}

///|
/// Convert Group Velocity Dispersion (GVD) beta2 (s^2/m) to D parameter (ps/(nm*km))
pub fn beta2_to_d(beta2 : Double, wavelength_m : Double) -> Double {
  let factor = -(2.0 * PI * C_LIGHT) / (wavelength_m * wavelength_m)
  beta2 * factor * 1.0e-6
}

///|
/// Convert Dispersion D parameter (ps/(nm*km)) to GVD beta2 (s^2/m)
pub fn d_to_beta2_param(d_param : Double, wavelength_m : Double) -> Double {
  let factor = -(wavelength_m * wavelength_m) / (2.0 * PI * C_LIGHT)
  d_param * 1.0e-6 * factor
}

///|
/// Convert energy density (J) to average power (W) given repetition rate f_rep (Hz)
pub fn energy_to_average_power(
  energy_j : Double,
  rep_rate_hz : Double,
) -> Double {
  energy_j * rep_rate_hz
}

///|
/// Convert average power (W) to pulse energy (J) given repetition rate f_rep (Hz)
pub fn average_power_to_energy(
  avg_power_w : Double,
  rep_rate_hz : Double,
) -> Double {
  if rep_rate_hz <= 0.0 {
    0.0
  } else {
    avg_power_w / rep_rate_hz
  }
}

///|
/// Calculate peak power P0 (W) from pulse energy E (J) and FWHM duration for Sech pulse
pub fn energy_to_sech_peak_power(
  energy_j : Double,
  fwhm_duration : Double,
) -> Double {
  let t0 = fwhm_duration / (2.0 * @math.ln(1.0 + @math.pow(2.0, 0.5)))
  energy_j / (2.0 * t0)
}

///|
/// Calculate peak power P0 (W) from pulse energy E (J) and FWHM duration for Gaussian pulse
pub fn energy_to_gaussian_peak_power(
  energy_j : Double,
  fwhm_duration : Double,
) -> Double {
  let t0 = fwhm_duration / (2.0 * @math.pow(2.0 * @math.ln(2.0), 0.5))
  energy_j / (@math.pow(PI, 0.5) * t0)
}

///|
/// Convert temporal grid time step dt to frequency grid span F_span (Hz)
pub fn dt_to_frequency_span(dt : Double) -> Double {
  if dt <= 0.0 {
    0.0
  } else {
    1.0 / dt
  }
}

///|
/// Convert number of points N and time step dt to frequency resolution df (Hz)
pub fn grid_frequency_resolution(num_points : Int, dt : Double) -> Double {
  if num_points <= 0 || dt <= 0.0 {
    0.0
  } else {
    1.0 / (num_points.to_double() * dt)
  }
}