use super::conventions::WattsPerSquareMeterSteradianMicrometer;
use super::length::{Meter, Nanometers};
use super::radiometry::{
PhotonsPerSquareCentimeterNanosecondSteradianNanometer as SpectralBandPhotonRadiance, S10s,
WattsPerSquareMeterSteradianMeter, WattsPerSquareMeterSteradianNanometer,
};
use super::{energy, unit, Quantity};
pub(crate) type JouleMeters = Quantity<unit::Prod<unit::Joule, unit::Meter>>;
pub(crate) const HC: JouleMeters = JouleMeters::new(1.986_445_857_148_968e-25);
pub(crate) const S10_TO_W_M2_SR_UM: WattsPerSquareMeterSteradianMicrometer =
WattsPerSquareMeterSteradianMicrometer::new(1.28e-8);
pub(crate) const S10_TO_W_M2_SR_NM: WattsPerSquareMeterSteradianNanometer =
S10_TO_W_M2_SR_UM.to_const::<unit::WattPerSquareMeterSteradianNanometer>();
pub(crate) fn s10_for_spectral_photon_radiance(
density: SpectralBandPhotonRadiance,
wavelength: Nanometers,
) -> S10s {
let wavelength_m = wavelength.to::<Meter>();
let photon_energy = energy::Joules::new(HC.value() / wavelength_m.value());
let spectral_radiance_per_m = WattsPerSquareMeterSteradianMeter::new(
density
.to::<unit::PhotonPerSquareMeterSecondSteradianMeter>()
.value()
* photon_energy.value(),
);
let spectral_radiance_per_nm =
spectral_radiance_per_m.to::<unit::WattPerSquareMeterSteradianNanometer>();
S10s::new(spectral_radiance_per_nm.value() / S10_TO_W_M2_SR_NM.value())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn s10_calibration_constants_preserve_historical_um_and_nm_values() {
assert!((S10_TO_W_M2_SR_UM.value() - 1.28e-8).abs() < 1.0e-20);
assert!((S10_TO_W_M2_SR_NM.value() - 1.28e-11).abs() < 1.0e-23);
}
}