use super::*;
use crate::{
ffi::ffi_test_helpers::{
ffi_boxed_slice_to_array, get_test_ffi_correlator_context_legacy,
get_test_ffi_metafits_context,
},
metafits_context::ffi::{
mwalib_metafits_context_display, mwalib_metafits_context_free, mwalib_metafits_context_new,
mwalib_metafits_context_new2, mwalib_metafits_metadata_free, mwalib_metafits_metadata_get,
MetafitsMetadata,
},
};
use float_cmp::{approx_eq, F64Margin};
use libc::size_t;
use std::ffi::{c_char, CStr, CString};
#[test]
fn test_mwalib_metafits_context_new_valid() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_file =
CString::new("test_files/1101503312_1_timestep/1101503312.metafits").unwrap();
let metafits_file_ptr = metafits_file.as_ptr();
unsafe {
let mut metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut();
let retval = mwalib_metafits_context_new(
metafits_file_ptr,
MWAVersion::CorrLegacy,
&mut metafits_context_ptr,
error_message_ptr,
error_len,
);
assert_eq!(retval, 0, "mwalib_metafits_context_new failure");
let context_ptr = metafits_context_ptr.as_mut();
assert!(context_ptr.is_some());
assert_eq!(mwalib_metafits_context_free(context_ptr.unwrap()), 0);
assert_eq!(mwalib_metafits_context_free(std::ptr::null_mut()), 0);
}
}
#[test]
fn test_mwalib_metafits_context_new_invalid() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_file =
CString::new("test_files/1101503312_1_timestep/missing_file.metafits").unwrap();
let metafits_file_ptr = metafits_file.as_ptr();
unsafe {
let mut metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut();
let retval = mwalib_metafits_context_new(
metafits_file_ptr,
MWAVersion::CorrLegacy,
&mut metafits_context_ptr,
error_message_ptr,
error_len,
);
assert_ne!(retval, 0);
let mut ret_error_message: String = String::new();
if retval != 0 {
let c_str: &CStr = CStr::from_ptr(error_message_ptr);
let str_slice: &str = c_str.to_str().unwrap();
str_slice.clone_into(&mut ret_error_message);
}
assert!(!ret_error_message.is_empty());
}
}
#[test]
fn test_mwalib_metafits_context_display() {
let metafits_context_ptr: *mut MetafitsContext =
get_test_ffi_metafits_context(MWAVersion::CorrLegacy);
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let buf_len: size_t = 1280;
let buf_message = CString::new(" ".repeat(buf_len)).unwrap();
let buf_message_ptr = buf_message.as_ptr() as *mut c_char;
unsafe {
let retval = mwalib_metafits_context_display(
metafits_context_ptr,
buf_message_ptr,
buf_len,
error_message_ptr,
error_len,
);
assert_eq!(retval, 0);
let output_str = CStr::from_ptr(buf_message_ptr)
.to_str()
.expect("Error converting C string");
assert!(output_str.starts_with("MetafitsContext ("));
}
}
#[test]
fn test_mwalib_metafits_context_new_guess_mwa_version() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_file =
CString::new("test_files/1101503312_1_timestep/1101503312.metafits").unwrap();
let metafits_file_ptr = metafits_file.as_ptr();
unsafe {
let mut metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut();
let retval = mwalib_metafits_context_new2(
metafits_file_ptr,
&mut metafits_context_ptr,
error_message_ptr,
error_len,
);
assert_eq!(retval, 0, "mwalib_metafits_context_new failure");
let context_ptr = metafits_context_ptr.as_mut();
assert!(context_ptr.is_some());
let metafits_context = context_ptr.unwrap();
assert_eq!(
metafits_context.mwa_version.unwrap(),
MWAVersion::CorrLegacy
);
}
}
#[test]
fn test_mwalib_metafits_context_display_null_ptr() {
let metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut();
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let buf_len: size_t = 1280;
let buf_message = CString::new(" ".repeat(buf_len)).unwrap();
let buf_message_ptr = buf_message.as_ptr() as *mut c_char;
unsafe {
let retval = mwalib_metafits_context_display(
metafits_context_ptr,
buf_message_ptr,
buf_len,
error_message_ptr,
error_len,
);
assert_ne!(retval, 0);
}
}
#[test]
fn test_mwalib_metafits_metadata_get_from_metafits_context_get_and_free() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_context_ptr: *mut MetafitsContext =
get_test_ffi_metafits_context(MWAVersion::CorrLegacy);
unsafe {
let context_ptr = metafits_context_ptr.as_mut();
assert!(context_ptr.is_some());
let mut metafits_metadata_ptr: *mut MetafitsMetadata = std::ptr::null_mut();
let retval = mwalib_metafits_metadata_get(
metafits_context_ptr,
std::ptr::null_mut(),
std::ptr::null_mut(),
&mut metafits_metadata_ptr,
error_message_ptr,
error_len,
);
let mut ret_error_message: String = String::new();
if retval != 0 {
let c_str: &CStr = CStr::from_ptr(error_message_ptr);
let str_slice: &str = c_str.to_str().unwrap();
str_slice.clone_into(&mut ret_error_message);
}
assert_eq!(
retval, 0,
"mwalib_metafits_metadata_get failure {}",
ret_error_message
);
let metafits_metadata = Box::from_raw(metafits_metadata_ptr);
assert_eq!(
mwalib_metafits_metadata_free(Box::into_raw(metafits_metadata)),
0
);
assert_eq!(mwalib_metafits_metadata_free(std::ptr::null_mut()), 0);
}
}
#[test]
fn test_mwalib_metafits_metadata_get_from_metafits_context_valid() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_context_ptr: *mut MetafitsContext =
get_test_ffi_metafits_context(MWAVersion::CorrLegacy);
unsafe {
let context_ptr = metafits_context_ptr.as_mut();
assert!(context_ptr.is_some());
let mut metafits_metadata_ptr: *mut MetafitsMetadata = std::ptr::null_mut();
let retval = mwalib_metafits_metadata_get(
metafits_context_ptr,
std::ptr::null_mut(),
std::ptr::null_mut(),
&mut metafits_metadata_ptr,
error_message_ptr,
error_len,
);
let mut ret_error_message: String = String::new();
if retval != 0 {
let c_str: &CStr = CStr::from_ptr(error_message_ptr);
let str_slice: &str = c_str.to_str().unwrap();
str_slice.clone_into(&mut ret_error_message);
}
assert_eq!(
retval, 0,
"mwalib_metafits_metadata_get failure {}",
ret_error_message
);
let metafits_metadata = Box::from_raw(metafits_metadata_ptr);
assert_eq!(metafits_metadata.obs_id, 1_101_503_312);
let item: Vec<baseline::ffi::Baseline> =
ffi_boxed_slice_to_array(metafits_metadata.baselines, metafits_metadata.num_baselines);
assert_eq!(item.len(), 8256, "Array length is not correct");
assert_eq!(item[2].ant1_index, 0);
assert_eq!(item[2].ant2_index, 2);
let item: Vec<antenna::ffi::Antenna> =
ffi_boxed_slice_to_array(metafits_metadata.antennas, metafits_metadata.num_ants);
assert_eq!(item.len(), 128, "Array length is not correct");
assert_eq!(
CString::from_raw(item[127].tile_name),
CString::new("Tile168").unwrap()
);
assert_eq!(item[2].tile_id, 13);
let item: Vec<rfinput::ffi::Rfinput> =
ffi_boxed_slice_to_array(metafits_metadata.rf_inputs, metafits_metadata.num_rf_inputs);
assert_eq!(item.len(), 256, "Array length is not correct");
assert_eq!(item[2].ant, 1);
assert_eq!(
CString::from_raw(item[2].tile_name),
CString::new("Tile012").unwrap()
);
assert_eq!(CString::from_raw(item[2].pol), CString::new("X").unwrap());
assert_eq!(item[2].num_digital_gains, 24);
let rfinput_digital_gains =
ffi_boxed_slice_to_array(item[2].digital_gains, item[2].num_digital_gains);
assert_eq!(item[2].num_digital_gains, rfinput_digital_gains.len());
assert!(item[2].calib_delay.is_nan());
assert_eq!(item[2].num_calib_gains, 24);
assert_eq!(
item[0].signal_chain_corrections_index,
MAX_RECEIVER_CHANNELS
);
assert!(approx_eq!(
f64,
rfinput_digital_gains[4],
76. / 64.,
F64Margin::default()
));
assert_eq!(item[2].num_dipole_delays, 16);
let rfinput_dipole_delays =
ffi_boxed_slice_to_array(item[2].dipole_delays, item[2].num_dipole_delays);
assert_eq!(item[2].num_dipole_delays, rfinput_dipole_delays.len());
assert_eq!(rfinput_dipole_delays[0], 0);
assert_eq!(item[2].num_dipole_gains, 16);
let rfinput_dipole_gains =
ffi_boxed_slice_to_array(item[2].dipole_gains, item[2].num_dipole_gains);
assert_eq!(item[2].num_dipole_gains, rfinput_dipole_gains.len());
assert!(approx_eq!(
f64,
rfinput_dipole_gains[0],
1.0,
F64Margin::default()
));
assert_eq!(item[2].rec_type, ReceiverType::Unknown);
let item: Vec<coarse_channel::ffi::CoarseChannel> = ffi_boxed_slice_to_array(
metafits_metadata.metafits_coarse_chans,
metafits_metadata.num_metafits_coarse_chans,
);
assert_eq!(item.len(), 24, "Array length is not correct");
assert_eq!(item[0].rec_chan_number, 109);
let item: Vec<timestep::ffi::TimeStep> = ffi_boxed_slice_to_array(
metafits_metadata.metafits_timesteps,
metafits_metadata.num_metafits_timesteps,
);
assert_eq!(item.len(), 56, "Array length is not correct");
assert_eq!(item[0].unix_time_ms, 1_417_468_096_000);
assert_eq!(item[55].unix_time_ms, 1_417_468_206_000);
assert!(!metafits_metadata.oversampled);
assert!(!metafits_metadata.deripple_applied);
assert_eq!(
CString::from_raw(metafits_metadata.deripple_param),
CString::new("").unwrap()
);
assert!(!metafits_metadata.calibration_delays_and_gains_applied);
assert!(!metafits_metadata.signal_chain_corrections_applied);
if metafits_metadata.num_signal_chain_corrections > 0 {
let sig_chain_corrs = ffi_boxed_slice_to_array(
metafits_metadata.signal_chain_corrections,
metafits_metadata.num_signal_chain_corrections,
);
assert_eq!(
sig_chain_corrs.len(),
metafits_metadata.num_signal_chain_corrections
);
}
}
}
#[test]
fn test_mwalib_metafits_metadata_get_from_metafits_context_legacy_vcs_valid() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
let metafits_context_ptr: *mut MetafitsContext =
get_test_ffi_metafits_context(MWAVersion::VCSLegacyRecombined);
unsafe {
let context_ptr = metafits_context_ptr.as_mut();
assert!(context_ptr.is_some());
let mut metafits_metadata_ptr: *mut MetafitsMetadata = std::ptr::null_mut();
let retval = mwalib_metafits_metadata_get(
metafits_context_ptr,
std::ptr::null_mut(),
std::ptr::null_mut(),
&mut metafits_metadata_ptr,
error_message_ptr,
error_len,
);
let mut ret_error_message: String = String::new();
if retval != 0 {
let c_str: &CStr = CStr::from_ptr(error_message_ptr);
let str_slice: &str = c_str.to_str().unwrap();
str_slice.clone_into(&mut ret_error_message);
}
assert_eq!(
retval, 0,
"mwalib_metafits_metadata_get failure {}",
ret_error_message
);
let metafits_metadata = Box::from_raw(metafits_metadata_ptr);
let items: Vec<antenna::ffi::Antenna> =
ffi_boxed_slice_to_array(metafits_metadata.antennas, metafits_metadata.num_ants);
assert_eq!(items.len(), 128, "Array length is not correct");
for item in items {
if item.tile_id == 154 {
assert_eq!(item.rfinput_y, 1);
} else if item.tile_id == 104 {
assert_eq!(item.rfinput_y, 0);
}
}
}
}
#[test]
fn test_mwalib_metafits_metadata_get_null_contexts() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
unsafe {
let mut metafits_metadata_ptr: *mut MetafitsMetadata = std::ptr::null_mut();
let ret_val = mwalib_metafits_metadata_get(
std::ptr::null_mut(),
std::ptr::null_mut(),
std::ptr::null_mut(),
&mut metafits_metadata_ptr,
error_message_ptr,
error_len,
);
assert_ne!(ret_val, 0);
}
}
#[test]
fn test_mwalib_metafits_metadata_get_from_correlator_context_valid() {
let error_len: size_t = 128;
let error_message = CString::new(" ".repeat(error_len)).unwrap();
let error_message_ptr = error_message.as_ptr() as *mut c_char;
unsafe {
let correlator_context_ptr: *mut CorrelatorContext =
get_test_ffi_correlator_context_legacy();
let context_ptr = correlator_context_ptr.as_mut();
assert!(context_ptr.is_some());
let mut metafits_metadata_ptr: *mut MetafitsMetadata = std::ptr::null_mut();
let retval = mwalib_metafits_metadata_get(
std::ptr::null_mut(),
correlator_context_ptr,
std::ptr::null_mut(),
&mut metafits_metadata_ptr,
error_message_ptr,
error_len,
);
assert_eq!(
retval, 0,
"mwalib_metafits_metadata_get did not return success"
);
let metafits_metadata = Box::from_raw(metafits_metadata_ptr);
assert_eq!(metafits_metadata.obs_id, 1_101_503_312);
assert_eq!(
mwalib_metafits_metadata_free(Box::into_raw(metafits_metadata)),
0
);
assert_eq!(mwalib_metafits_metadata_free(std::ptr::null_mut()), 0);
}
}