#[cfg(feature = "serde")]
use serde::Serialize;
mod sv;
pub use sv::SvAntenna;
use crate::{
linspace::Linspace,
prelude::{Epoch, ParsingError},
};
#[derive(Default, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum CalibrationMethod {
#[default]
Unknown,
Chamber,
Field,
Robot,
Copied,
Converted,
}
impl std::str::FromStr for CalibrationMethod {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_lowercase().as_str() {
"chamber" => Ok(Self::Chamber),
"field" => Ok(Self::Field),
"robot" => Ok(Self::Robot),
"copied" => Ok(Self::Copied),
"converted" => Ok(Self::Converted),
"" => Ok(Self::Unknown),
_ => Err(ParsingError::AntexCalibrationMethod),
}
}
}
#[derive(Default, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Calibration {
pub method: CalibrationMethod,
pub agency: String,
pub date: Epoch,
pub number: u16,
pub validity_period: Option<(Epoch, Epoch)>,
}
#[derive(Default, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Antenna {
pub specific: AntennaSpecific,
pub calibration: Calibration,
pub zenith_grid: Linspace,
pub azi_inc: f64,
pub sinex_code: String,
}
impl Antenna {
pub fn is_valid(&self, now: Epoch) -> bool {
if let Some((from, until)) = self.calibration.validity_period {
now > from && now < until
} else {
true
}
}
pub fn with_calibration(&self, calib: Calibration) -> Self {
let mut a = self.clone();
a.calibration = calib.clone();
a
}
pub fn with_zenith_grid(&self, grid: Linspace) -> Self {
let mut a = self.clone();
a.zenith_grid = grid.clone();
a
}
pub fn with_validity_period(&self, start: Epoch, end: Epoch) -> Self {
let mut a = self.clone();
a.calibration.validity_period = Some((start, end));
a
}
pub fn with_dazi(&self, dazi: f64) -> Self {
let mut a = self.clone();
a.azi_inc = dazi;
a
}
pub fn with_specificities(&self, specs: AntennaSpecific) -> Self {
let mut a = self.clone();
a.specific = specs.clone();
a
}
}
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum AntennaSpecific {
RxAntenna(RxAntenna),
SvAntenna(sv::SvAntenna),
}
impl Default for AntennaSpecific {
fn default() -> Self {
Self::RxAntenna(RxAntenna::default())
}
}
#[derive(Clone, Debug)]
pub enum AntennaMatcher {
IGSCode(String),
SerialNumber(String),
}
impl AntennaMatcher {
#[cfg(feature = "antex")]
pub(crate) fn to_lowercase(&self) -> Self {
match self {
Self::IGSCode(code) => Self::IGSCode(code.to_lowercase()),
Self::SerialNumber(sn) => Self::SerialNumber(sn.to_lowercase()),
}
}
}
#[derive(Default, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RxAntenna {
pub igs_type: String,
pub serial_number: Option<String>,
}