use crate::{
calibration_fit::{self, ffi},
ffi::{ffi_create_c_array, ffi_free_c_array},
MetafitsContext,
};
#[repr(C)]
pub struct CalibrationFit {
pub rf_input: usize,
pub delay_metres: f32,
pub intercept_metres: f32,
pub gains: *mut f32,
pub num_gains: usize,
pub gain_polynomial_fit0: *mut f32,
pub num_gain_polynomial_fit0: usize,
pub gain_polynomial_fit1: *mut f32,
pub num_gain_polynomial_fit1: usize,
pub phase_fit_quality: f32,
pub gain_fit_quality: f32,
}
impl CalibrationFit {
pub fn populate_array(metafits_context: &MetafitsContext) -> (*mut ffi::CalibrationFit, usize) {
let mut item_vec: Vec<ffi::CalibrationFit> = Vec::new();
if let Some(v) = &metafits_context.calibration_fits {
for item in v.iter() {
let out_item = {
let calibration_fit::CalibrationFit {
rf_input: _,
delay_metres,
intercept_metres,
gains,
num_gains: _,
gain_polynomial_fit0,
num_gain_polynomial_fit0: _,
gain_polynomial_fit1,
num_gain_polynomial_fit1: _,
phase_fit_quality,
gain_fit_quality,
} = item;
let (gains_ptr, gains_len) = ffi_create_c_array(gains.clone());
let (gain_polynomial_fit0_ptr, gain_polynomial_fit0_len) =
ffi_create_c_array(gain_polynomial_fit0.clone());
let (gain_polynomial_fit1_ptr, gain_polynomial_fit1_len) =
ffi_create_c_array(gain_polynomial_fit1.clone());
calibration_fit::ffi::CalibrationFit {
rf_input: metafits_context
.rf_inputs
.iter()
.position(|x| x.ant == item.rf_input.ant && x.pol == item.rf_input.pol)
.unwrap(),
delay_metres: *delay_metres,
intercept_metres: *intercept_metres,
gains: gains_ptr,
num_gains: gains_len,
gain_polynomial_fit0: gain_polynomial_fit0_ptr,
num_gain_polynomial_fit0: gain_polynomial_fit0_len,
gain_polynomial_fit1: gain_polynomial_fit1_ptr,
num_gain_polynomial_fit1: gain_polynomial_fit1_len,
phase_fit_quality: *phase_fit_quality,
gain_fit_quality: *gain_fit_quality,
}
};
item_vec.push(out_item);
}
}
ffi_create_c_array(item_vec)
}
fn destroy_item(item: *mut ffi::CalibrationFit) {
if item.is_null() {
return;
}
let a = unsafe { &mut *item };
if !a.gains.is_null() {
ffi_free_c_array(a.gains, a.num_gains);
}
if !a.gain_polynomial_fit0.is_null() {
ffi_free_c_array(a.gain_polynomial_fit0, a.num_gain_polynomial_fit0);
}
if !a.gain_polynomial_fit1.is_null() {
ffi_free_c_array(a.gain_polynomial_fit1, a.num_gain_polynomial_fit1);
}
}
pub fn destroy_array(items_ptr: *mut ffi::CalibrationFit, items_len: usize) {
let items_slice = unsafe { std::slice::from_raw_parts_mut(items_ptr, items_len) };
for item in items_slice {
Self::destroy_item(item);
}
ffi_free_c_array(items_ptr, items_len);
}
}