use itertools::multizip;
#[test]
#[serial]
fn das() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let handle = spice::dasopr("/Users/gregoireh/data/spice-kernels/hera/kernels/dsk/g_08438mm_lgt_obj_didb_0000n00000_v002.bds");
let (dladsc, found) = spice::dlabfs(handle);
assert!(found);
let dskdsc = spice::dskgd(handle, dladsc);
let rmax = dskdsc.co3max;
assert!(rmax > 0f64);
spice::dascls(handle);
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn dskp02() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let handle = spice::dasopr("/Users/gregoireh/data/spice-kernels/hera/kernels/dsk/g_08438mm_lgt_obj_didb_0000n00000_v002.bds");
let (dladsc, _) = spice::dlabfs(handle);
let plates = spice::dskp02(handle, dladsc);
let expected_first_plate = [1, 2, 3];
let expected_last_plate = [1538, 849, 848];
assert_eq!(plates.len(), 3072);
for (component, expected_component) in
multizip((plates.first().unwrap().iter(), expected_first_plate.iter()))
{
assert_eq!(component, expected_component);
}
for (component, expected_component) in
multizip((plates.last().unwrap().iter(), expected_last_plate.iter()))
{
assert_eq!(component, expected_component);
}
spice::kclear();
}
#[test]
#[serial]
fn georec() {
const CLARK66_RADIUS: f64 = 6378.2064;
const CLARK66_FLATTENING: f64 = 1.0 / 294.9787;
let test_data: [[f64; 6]; 11] = [
[0.0000, 90.0000, -6356.5838, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, -6377.2063, 1.0000, 0.0000, 0.0000],
[90.0000, 0.0000, -6377.2063, 0.0000, 1.0000, 0.0000],
[0.0000, 90.0000, -6355.5838, 0.0000, 0.0000, 1.0000],
[180.0000, 0.0000, -6377.2063, -1.0000, 0.0000, 0.0000],
[-90.0000, 0.0000, -6377.2063, 0.0000, -1.0000, 0.0000],
[0.0000, -90.0000, -6355.5838, 0.0000, 0.0000, -1.0000],
[45.0000, 0.0000, -6376.7921, 1.0000, 1.0000, 0.0000],
[0.0000, 88.7070, -6355.5725, 1.0000, 0.0000, 1.0000],
[90.0000, 88.7070, -6355.5725, 0.0000, 1.0000, 1.0000],
[45.0000, 88.1713, -6355.5612, 1.0000, 1.0000, 1.0000],
];
for test in test_data.iter() {
let rect = spice::georec(
test[0].to_radians(),
test[1].to_radians(),
test[2],
CLARK66_RADIUS,
CLARK66_FLATTENING,
);
assert_relative_eq!(rect[0], test[3], epsilon = 0.0001);
assert_relative_eq!(rect[1], test[4], epsilon = 0.0001);
assert_relative_eq!(rect[2], test[5], epsilon = 0.0001);
}
}
#[test]
#[serial]
fn pxform() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let et = spice::str2et("2027-MAR-23 16:00:00");
let matrix = spice::pxform("J2000", "ECLIPJ2000", et);
let expected_matrix = [
[1.0, 0.0, 0.0],
[0.0, 0.9174820620691818, 0.3977771559319137],
[0.0, -0.3977771559319137, 0.9174820620691818],
];
for (row, expected_row) in multizip((matrix.iter(), expected_matrix.iter())) {
for (component, expected_component) in multizip((row.iter(), expected_row.iter())) {
assert_relative_eq!(component, expected_component, epsilon = f64::EPSILON);
}
}
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn pxfrm2() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let etfrom = spice::str2et("2027-MAR-23 16:00:00");
let etto = etfrom + 30.0 * 60.0; let matrix = spice::pxfrm2("J2000", "J2000", etfrom, etto);
let expected_matrix = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]];
for (row, expected_row) in multizip((matrix.iter(), expected_matrix.iter())) {
for (component, expected_component) in multizip((row.iter(), expected_row.iter())) {
assert_relative_eq!(component, expected_component, epsilon = f64::EPSILON);
}
}
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn radrec() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let ra = 51.080_f64.to_radians();
let dec = 49.861_f64.to_radians();
let j2000_rect = spice::radrec(1.0, ra, dec);
let mat = spice::pxform("J2000", "B1950", 0.0);
let b1950_rect = spice::mxv(mat, j2000_rect);
let (_, ra, dec) = spice::recrad(b1950_rect);
let ra_b1950 = 50.185_f64;
let dec_b1950 = 49.684_f64;
assert_relative_eq!(ra.to_degrees(), ra_b1950, epsilon = 0.001);
assert_relative_eq!(dec.to_degrees(), dec_b1950, epsilon = 0.001);
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn spkezr() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let et = spice::str2et("2021-01-06 09:36:09.1825432 TDB");
let (sun_ssb_posvec, _sun_ssb_lt) = spice::spkezr("sun", et, "j2000", "none", "ssb");
let (earth_ssb_posvec, _earth_ssb_lt) = spice::spkezr("earth", et, "j2000", "none", "ssb");
let (earth_sun_posvec, _earth_sun_ly) = spice::spkezr("earth", et, "j2000", "none", "sun");
assert_eq!(earth_ssb_posvec[3] - sun_ssb_posvec[3], earth_sun_posvec[3]);
assert_eq!(earth_ssb_posvec[4] - sun_ssb_posvec[4], earth_sun_posvec[4]);
assert_eq!(earth_ssb_posvec[5] - sun_ssb_posvec[5], earth_sun_posvec[5]);
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
fn get_temp_filepath(fname: &str) -> String {
let mut filepath = std::env::temp_dir()
.into_os_string()
.into_string()
.expect("Failed to get temporary directory path");
filepath.push_str(fname);
filepath
}
fn delete_if_exists(file: &std::path::Path) {
if file.exists() {
std::fs::remove_file(&file).unwrap();
}
}
fn junk_spkw09_c(handle: i32) {
const N_STATES: usize = 4;
unsafe {
spice::c::spkw09_c(
handle,
399,
10,
spice::cstr!("J2000"),
0.0,
(N_STATES - 1) as f64,
spice::cstr!("Segment ID"),
3,
N_STATES as i32,
[[0f64; 6]; N_STATES].as_mut_ptr(),
(0..N_STATES)
.map(|i| i as f64)
.collect::<Vec<f64>>()
.as_mut_ptr(),
);
}
}
fn open_test_spk(filepath: &str) -> i32 {
let mut handle = 0;
unsafe {
spice::c::spkopn_c(
spice::cstr!(filepath),
spice::cstr!("SPK Kernel File"),
0,
&mut handle,
)
}
handle
}
#[test]
#[serial]
fn spkcls() {
let filepath = get_temp_filepath("/spkclstestkernel.bsp");
let file = std::path::Path::new(&filepath);
delete_if_exists(file);
let handle = open_test_spk(&filepath);
junk_spkw09_c(handle);
spice::spkcls(handle);
assert!(file.exists());
std::fs::remove_file(file).unwrap();
}
#[test]
#[serial]
fn spkopn() {
let filepath = get_temp_filepath("/spkopntestkernel.bsp");
let file = std::path::Path::new(&filepath);
delete_if_exists(file);
let handle = spice::spkopn(&filepath, "SPK Kernel File", 60);
junk_spkw09_c(handle);
unsafe { spice::c::spkcls_c(handle) }
assert!(file.exists());
std::fs::remove_file(file).unwrap();
}
#[test]
#[serial]
fn spkw09() {
let filepath = get_temp_filepath("/spkw09testkernel.bsp");
let file = std::path::Path::new(&filepath);
delete_if_exists(file);
let handle = open_test_spk(&filepath);
const N_STATES: usize = 4;
spice::spkw09(
handle,
399,
10,
"J2000",
0.0,
(N_STATES - 1) as f64,
"Segment ID",
3,
4,
&mut [[0f64; 6]; N_STATES],
&mut (0..N_STATES).map(|i| i as f64).collect::<Vec<f64>>(),
);
unsafe { spice::c::spkcls_c(handle) }
assert!(file.exists());
std::fs::remove_file(file).unwrap();
}
#[test]
#[serial]
fn spkpos() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let et = spice::str2et("2027-MAR-23 16:00:00");
let (position, light_time) = spice::spkpos("DIMORPHOS", et, "J2000", "NONE", "HERA");
let expected_position = [19.880764225600004, 20.637995227402328, -4.208198899932672];
let expected_light_time = 9.661162013688976e-5;
for (component, expected_component) in multizip((position.iter(), expected_position.iter())) {
assert_relative_eq!(component, expected_component, epsilon = f64::EPSILON);
}
assert_relative_eq!(light_time, expected_light_time, epsilon = f64::EPSILON);
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn str2et() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let et = spice::str2et("2027-MAR-23 16:00:00");
assert_relative_eq!(et, 859089669.1856234, epsilon = f64::EPSILON);
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn timout() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let et = spice::str2et("2027-MAR-23 16:00:00");
let date = spice::timout(et, spice::TIME_FORMAT);
assert_eq!(date, "2027-MAR-23 16:00:00");
spice::unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
}
#[test]
#[serial]
fn vdot() {
assert_eq!(spice::vdot([1.0, 2.0, 3.0], [1.0, 2.0, 3.0]), 14.0)
}
#[test]
#[serial]
fn vcrss() {
assert_eq!(
spice::vcrss([0.0, 1.0, 0.0], [1.0, 0.0, 0.0]),
[0.0, 0.0, -1.0]
);
assert_eq!(
spice::vcrss([5.0, 5.0, 5.0], [-1.0, -1.0, -1.0]),
[0.0, 0.0, 0.0]
);
}
#[test]
#[serial]
fn vsep() {
let ang_1 = spice::vsep([1., 0., 0.], [1., 0., 0.]);
let ang_2 = spice::vsep([1., 0., 0.], [0., 1., 0.]);
assert_relative_eq!(ang_1, 0.0, epsilon = f64::EPSILON);
assert_relative_eq!(ang_2, std::f64::consts::TAU / 4., epsilon = f64::EPSILON);
}
#[test]
#[serial]
fn kdata() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let index_dsk = 1;
let count = spice::ktotal("dsk");
assert_eq!(count, 2);
let (file, filtyp, source, handle, found) = spice::kdata(index_dsk, "dsk");
assert_eq!(
file,
"/Users/gregoireh/data/spice-kernels/hera/kernels/dsk/g_08438mm_lgt_obj_didb_0000n00000_v002.bds"
);
assert_eq!(filtyp, "DSK");
assert_eq!(source, "/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
assert!(handle.is_positive());
assert_eq!(found, true);
spice::kclear();
}
#[test]
#[serial]
fn cell() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let (file, _, _, _, found) = spice::kdata(1, "dsk");
assert!(found);
let cell = spice::dskobj(&file);
assert_eq!(cell.card, 1);
assert_eq!(cell.get_data_int(0), -658031);
assert_eq!(spice::bodc2n(cell.get_data_int(0)).0, "DIMORPHOS");
spice::kclear();
}
#[test]
#[serial]
fn bodfnd() {
spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
let (target, found) = spice::bodn2c("DIMORPHOS");
assert!(found);
assert_eq!(target, -658031);
let found = spice::bodfnd(target, "RADII");
assert!(found);
spice::kclear();
}