use crate::error::{AstroError, Result};
use crate::time::julian_date;
use chrono::{DateTime, Utc};
use std::f64::consts::PI;
pub const ABERRATION_CONSTANT: f64 = 20.49552;
pub fn apply_aberration(
ra_j2000: f64,
dec_j2000: f64,
date: DateTime<Utc>,
) -> Result<(f64, f64)> {
if !(0.0..360.0).contains(&ra_j2000) {
return Err(AstroError::InvalidCoordinate {
coord_type: "right ascension",
value: ra_j2000,
valid_range: "[0, 360)",
});
}
if !(-90.0..=90.0).contains(&dec_j2000) {
return Err(AstroError::InvalidCoordinate {
coord_type: "declination",
value: dec_j2000,
valid_range: "[-90, 90]",
});
}
let ra_rad = ra_j2000.to_radians();
let dec_rad = dec_j2000.to_radians();
let jd_utc = julian_date(date);
use crate::time_scales::utc_to_tt_jd;
let jd_tt = utc_to_tt_jd(jd_utc);
let pr = 0.0; let pd = 0.0; let px = 0.0; let rv = 0.0;
let (ra_cirs, dec_cirs, _eo) = erfars::astrometry::Atci13(
ra_rad, dec_rad, pr, pd, px, rv, jd_tt, 0.0,
);
let mut ra_apparent = ra_cirs.to_degrees();
let dec_apparent = dec_cirs.to_degrees();
if ra_apparent < 0.0 {
ra_apparent += 360.0;
} else if ra_apparent >= 360.0 {
ra_apparent -= 360.0;
}
Ok((ra_apparent, dec_apparent))
}
pub fn remove_aberration(
ra_apparent: f64,
dec_apparent: f64,
date: DateTime<Utc>,
) -> Result<(f64, f64)> {
if !(0.0..360.0).contains(&ra_apparent) {
return Err(AstroError::InvalidCoordinate {
coord_type: "right ascension",
value: ra_apparent,
valid_range: "[0, 360)",
});
}
if !(-90.0..=90.0).contains(&dec_apparent) {
return Err(AstroError::InvalidCoordinate {
coord_type: "declination",
value: dec_apparent,
valid_range: "[-90, 90]",
});
}
let ra_rad = ra_apparent.to_radians();
let dec_rad = dec_apparent.to_radians();
let jd_utc = julian_date(date);
use crate::time_scales::utc_to_tt_jd;
let jd_tt = utc_to_tt_jd(jd_utc);
let (ra_icrs, dec_icrs, _eo) = erfars::astrometry::Atic13(
ra_rad, dec_rad, jd_tt, 0.0,
);
let mut ra_mean = ra_icrs.to_degrees();
let dec_mean = dec_icrs.to_degrees();
if ra_mean < 0.0 {
ra_mean += 360.0;
} else if ra_mean >= 360.0 {
ra_mean -= 360.0;
}
Ok((ra_mean, dec_mean))
}
pub fn aberration_magnitude(
ra_j2000: f64,
dec_j2000: f64,
date: DateTime<Utc>,
) -> Result<f64> {
let (ra_app, dec_app) = apply_aberration(ra_j2000, dec_j2000, date)?;
let ra1_rad = ra_j2000.to_radians();
let ra2_rad = ra_app.to_radians();
let dec1_rad = dec_j2000.to_radians();
let dec2_rad = dec_app.to_radians();
let sin_dec_diff = ((dec2_rad - dec1_rad) / 2.0).sin();
let sin_ra_diff = ((ra2_rad - ra1_rad) / 2.0).sin();
let a = sin_dec_diff * sin_dec_diff +
dec1_rad.cos() * dec2_rad.cos() * sin_ra_diff * sin_ra_diff;
let sep_rad = 2.0 * a.sqrt().asin();
Ok(sep_rad * 180.0 / PI * 3600.0)
}