use rfconversions::noise::noise_power_from_bandwidth;
use rfconversions::power::watts_to_dbm;
#[doc(alias = "G/T")]
pub struct Receiver {
pub gain: f64,
pub temperature: f64,
pub noise_figure: f64,
pub bandwidth: f64,
}
impl Receiver {
#[must_use]
pub fn calculate_noise_floor(&self) -> f64 {
let receiver_noise_floor_power =
noise_power_from_bandwidth(self.temperature, self.bandwidth);
watts_to_dbm(receiver_noise_floor_power)
}
#[must_use]
pub fn calculate_noise_power(&self) -> f64 {
self.calculate_noise_floor() + self.noise_figure
}
#[doc(alias = "G/T")]
#[must_use]
pub fn g_over_t_db(&self) -> f64 {
self.gain - 10.0 * self.temperature.log10()
}
#[doc(alias = "SNR")]
#[must_use]
pub fn calculate_snr(&self, input_power: f64) -> f64 {
let receiver_noise_floor_dbm = self.calculate_noise_floor();
let receiver_total_noise_power = receiver_noise_floor_dbm + self.noise_figure;
input_power - receiver_total_noise_power
}
}
#[cfg(test)]
mod tests {
use crate::receiver::Receiver;
#[test]
fn calculate_noise_floor() {
let receiver = Receiver {
gain: 10.0, temperature: 290.0,
noise_figure: 3.0, bandwidth: 100.0e6,
};
let noise_floor: f64 = receiver.calculate_noise_floor();
assert!((noise_floor - (-93.9772)).abs() < 0.01);
}
#[test]
fn calculate_noise_power() {
let receiver = Receiver {
gain: 10.0, temperature: 290.0,
noise_figure: 3.0,
bandwidth: 100.0e6,
};
let noise_power: f64 = receiver.calculate_noise_power();
assert!((noise_power - (-90.9772)).abs() < 0.01);
}
#[test]
fn g_over_t_db() {
let receiver = Receiver {
gain: 40.0,
temperature: 290.0,
noise_figure: 3.0,
bandwidth: 100.0e6,
};
let g_over_t = receiver.g_over_t_db();
let expected = 40.0 - 10.0 * 290.0_f64.log10();
assert!((g_over_t - expected).abs() < 1e-10);
}
#[test]
fn calculate_snr() {
let receiver = Receiver {
gain: 10.0, temperature: 290.0,
noise_figure: 3.0,
bandwidth: 100.0e6,
};
let input_power: f64 = -70.0;
let snr: f64 = receiver.calculate_snr(input_power);
assert!((snr - 20.9772).abs() < 0.01);
}
}