use super::*;
use std::fs::File;
use std::io::{Error, Write};
use tempfile::Builder;
fn generate_test_voltage_file(
temp_dir: &tempfile::TempDir,
filename: &str,
time_samples: usize,
rf_inputs: usize,
) -> Result<String, Error> {
let tdir_path = temp_dir.path();
let full_filename = tdir_path.join(filename);
let mut output_file = File::create(&full_filename)?;
let floats = time_samples * rf_inputs * 2;
let mut buffer: Vec<f32> = vec![0.0; floats];
let mut bptr: usize = 0;
for t in 0..time_samples {
for r in 0..rf_inputs {
buffer[bptr] = ((t * rf_inputs) + r) as f32 + 0.25;
bptr += 1;
buffer[bptr] = ((t * rf_inputs) + r) as f32 + 0.75;
bptr += 1;
}
}
output_file.write_all(misc::as_u8_slice(buffer.as_slice()))?;
output_file.flush()?;
Ok(String::from(full_filename.to_str().unwrap()))
}
#[test]
fn test_determine_voltage_file_unrecognised_files() {
let files = vec![
"1065880128_106588012_ch123.dat",
"106588012_1065880129_ch121.dat",
"1065880128_1065880128__ch121.dat",
"1065880128_1065880130_ch124.txt",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(matches!(
result.unwrap_err(),
VoltageFileError::Unrecognised(_)
));
}
#[test]
fn test_determine_voltage_file_gpstime_batches_proper_legacy_format() {
let files = vec![
"1065880128_1065880129_ch122.dat",
"1065880128_1065880129_ch21.dat",
"1065880128_1065880129_ch1.dat",
"1065880128_1065880128_ch21.dat",
"1065880128_1065880128_ch001.dat",
"1065880128_1065880128_ch122.dat",
"1065880128_1065880130_ch122.dat",
"1065880128_1065880130_ch021.dat",
"1065880128_1065880130_ch01.dat",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(result.is_ok(), "{:?}", result.unwrap_err());
let (temp_voltage_files, mwa_version, num_gputimes, voltage_file_interval_ms) = result.unwrap();
assert_eq!(mwa_version, MWAVersion::VCSLegacyRecombined);
assert_eq!(num_gputimes, 3);
assert_eq!(voltage_file_interval_ms, 1000);
let expected_voltage_files = vec![
TempVoltageFile {
filename: "1065880128_1065880128_ch001.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880128_ch21.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880128_ch122.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 122,
},
TempVoltageFile {
filename: "1065880128_1065880129_ch1.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880129,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880129_ch21.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880129,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880129_ch122.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880129,
channel_identifier: 122,
},
TempVoltageFile {
filename: "1065880128_1065880130_ch01.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880130,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880130_ch021.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880130,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880130_ch122.dat",
obs_id: 1065880128,
gps_time_seconds: 1065880130,
channel_identifier: 122,
},
];
assert_eq!(temp_voltage_files, expected_voltage_files);
}
#[test]
fn test_determine_voltage_file_gpstime_batches_proper_mwax_format() {
let files = vec![
"1065880128_1065880136_122.sub",
"1065880128_1065880136_21.sub",
"1065880128_1065880136_1.sub",
"1065880128_1065880128_21.sub",
"1065880128_1065880128_001.sub",
"1065880128_1065880128_122.sub",
"1065880128_1065880144_122.sub",
"1065880128_1065880144_021.sub",
"1065880128_1065880144_01.sub",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(result.is_ok(), "{:?}", result.unwrap_err());
let (temp_voltage_files, mwa_version, num_gputimes, voltage_file_interval_ms) = result.unwrap();
assert_eq!(mwa_version, MWAVersion::VCSMWAXv2);
assert_eq!(num_gputimes, 3);
assert_eq!(voltage_file_interval_ms, 8000);
let expected_voltage_files = vec![
TempVoltageFile {
filename: "1065880128_1065880128_001.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880128_21.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880128_122.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880128,
channel_identifier: 122,
},
TempVoltageFile {
filename: "1065880128_1065880136_1.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880136,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880136_21.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880136,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880136_122.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880136,
channel_identifier: 122,
},
TempVoltageFile {
filename: "1065880128_1065880144_01.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880144,
channel_identifier: 1,
},
TempVoltageFile {
filename: "1065880128_1065880144_021.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880144,
channel_identifier: 21,
},
TempVoltageFile {
filename: "1065880128_1065880144_122.sub",
obs_id: 1065880128,
gps_time_seconds: 1065880144,
channel_identifier: 122,
},
];
assert_eq!(temp_voltage_files, expected_voltage_files);
}
#[test]
fn test_determine_voltage_file_gpstime_batches_chan_mismatch() {
let files = vec![
"1065880128_1065880129_ch123.dat",
"1065880128_1065880129_ch121.dat",
"1065880128_1065880128_ch121.dat",
"1065880128_1065880130_ch124.dat",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(matches!(
result.unwrap_err(),
VoltageFileError::UnevenChannelsForGpsTime {
expected: _,
got: _
}
));
}
#[test]
fn test_determine_voltage_file_gpstime_batches_no_files() {
let files: Vec<String> = Vec::new();
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(matches!(
result.unwrap_err(),
VoltageFileError::NoVoltageFiles
));
}
#[test]
fn test_determine_voltage_file_mwa_version_mismatch() {
let files = vec![
"1065880128_1065880129_ch123.dat",
"1065880128_1065880129_121.sub",
"1065880128_1065880128_ch121.dat",
"1065880128_1065880130_ch124.dat",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(matches!(result.unwrap_err(), VoltageFileError::Mixture));
}
#[test]
fn test_determine_voltage_file_metafits_obs_id_mismatch() {
let files = vec![
"1065880128_1065880128_ch121.dat",
"1065880128_1065880129_ch121.dat",
"1065880128_1065880130_ch121.dat",
];
let result = determine_voltage_file_gpstime_batches(&files, 1234567890);
assert!(matches!(
result.unwrap_err(),
VoltageFileError::MetafitsObsidMismatch
));
}
#[test]
fn test_determine_voltage_file_gpstime_missing() {
let files = vec![
"1065880128_1065880128_ch121.dat",
"1065880128_1065880130_ch121.dat",
];
let result = determine_voltage_file_gpstime_batches(&files, 1065880128);
assert!(matches!(
result.unwrap_err(),
VoltageFileError::GpsTimeMissing {
expected: _,
got: _
}
));
}
#[test]
fn test_determine_obs_times_test_many_timesteps_legacy() {
let common_times: Vec<u64> = vec![1065880129, 1065880130, 1065880131, 1065880132, 1065880133];
let mut input = VoltageFileTimeMap::new();
let mut new_time_tree = BTreeMap::new();
new_time_tree.insert(121, String::from("1065880128_1065880128_ch120.dat"));
input.insert(1065880128, new_time_tree);
for time in common_times.iter() {
input
.entry(*time)
.or_default()
.entry(121)
.or_insert(format!("1065880128_{}_ch121.dat", time));
input
.entry(*time)
.or_default()
.entry(122)
.or_insert(format!("1065880128_{}_ch122.dat", time));
}
new_time_tree = BTreeMap::new();
new_time_tree.insert(121, String::from("1065880128_1065880134_ch120.dat"));
input.insert(1065880134, new_time_tree);
let interval: u64 = 1000; let expected_start: u64 = *common_times.first().unwrap() * 1000;
let expected_end: u64 = (*common_times.last().unwrap() * 1000) + interval;
let expected_duration = 5000;
let result = determine_common_obs_times_and_chans(&input, interval, None);
assert!(result.is_ok());
let result = result.unwrap();
assert!(result.is_some());
let result = result.unwrap();
assert_eq!(
result.start_gps_time_ms, expected_start,
"start_gps_time_ms incorrect {:?}",
result
);
assert_eq!(
result.end_gps_time_ms, expected_end,
"end_gps_time_ms incorrect {:?}",
result
);
assert_eq!(
result.duration_ms, expected_duration,
"duration_ms incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers.len(),
2,
"coarse_chan_identifiers is incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers[0], 121,
"coarse_chan_identifiers is incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers[1], 122,
"coarse_chan_identifiers is incorrect {:?}",
result
);
}
#[test]
fn test_determine_obs_times_test_many_timesteps_mwax() {
let common_times: Vec<u64> = vec![1065880136, 1065880144, 1065880152, 1065880160, 1065880168];
let mut input = VoltageFileTimeMap::new();
let mut new_time_tree = BTreeMap::new();
new_time_tree.insert(121, String::from("1065880128_1065880128_120.sub"));
input.insert(1065880128, new_time_tree);
for time in common_times.iter() {
input
.entry(*time)
.or_default()
.entry(121)
.or_insert(format!("1065880128_{}_121.sub", time));
input
.entry(*time)
.or_default()
.entry(122)
.or_insert(format!("1065880128_{}_122.sub", time));
}
new_time_tree = BTreeMap::new();
new_time_tree.insert(121, String::from("1065880128_1065880176_120.sub"));
input.insert(1065880176, new_time_tree);
let interval: u64 = 8000; let expected_start: u64 = *common_times.first().unwrap() * 1000;
let expected_end: u64 = (*common_times.last().unwrap() * 1000) + interval;
let expected_duration = 40000;
let result = determine_common_obs_times_and_chans(&input, interval, None);
assert!(result.is_ok());
let result = result.unwrap();
assert!(result.is_some());
let result = result.unwrap();
assert_eq!(
result.start_gps_time_ms, expected_start,
"start_gps_time_ms incorrect {:?}",
result
);
assert_eq!(
result.end_gps_time_ms, expected_end,
"end_gps_time_ms incorrect {:?}",
result
);
assert_eq!(
result.duration_ms, expected_duration,
"duration_ms incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers.len(),
2,
"coarse_chan_identifiers incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers[0], 121,
"coarse_chan_identifiers is incorrect {:?}",
result
);
assert_eq!(
result.coarse_chan_identifiers[1], 122,
"coarse_chan_identifiers is incorrect {:?}",
result
);
}
#[test]
fn test_voltage_file_batch_new() {
let new_batch = VoltageFileBatch::new(1234567890);
assert_eq!(new_batch.gps_time_seconds, 1234567890);
assert_eq!(new_batch.voltage_files.len(), 0);
}
#[test]
fn test_voltage_file_batch_partialeq() {
let mut batch1 = VoltageFileBatch::new(1234567890);
let voltage_file1 = VoltageFile {
filename: String::from("test.dat"),
channel_identifier: 123,
};
batch1.voltage_files.push(voltage_file1);
let mut batch2 = VoltageFileBatch::new(1234567890);
let voltage_file2 = VoltageFile {
filename: String::from("test.dat"),
channel_identifier: 123,
};
batch2.voltage_files.push(voltage_file2);
let mut batch3 = VoltageFileBatch::new(1234567890);
let voltage_file3 = VoltageFile {
filename: String::from("test1.dat"),
channel_identifier: 123,
};
batch3.voltage_files.push(voltage_file3);
let mut batch4 = VoltageFileBatch::new(9876543210);
let voltage_file4 = VoltageFile {
filename: String::from("test.dat"),
channel_identifier: 123,
};
batch4.voltage_files.push(voltage_file4);
assert_eq!(batch1, batch2);
assert_ne!(batch1, batch3);
assert_ne!(batch1, batch4);
}
#[test]
fn test_convert_temp_voltage_files() {
let temp_voltage_files: Vec<TempVoltageFile> = vec![
TempVoltageFile {
filename: "1234567000_1234567000_123.sub",
obs_id: 1234567000,
channel_identifier: 123,
gps_time_seconds: 1234567000,
},
TempVoltageFile {
filename: "1234567890_1234567008_124.sub",
obs_id: 1234567000,
channel_identifier: 124,
gps_time_seconds: 1234567008,
},
TempVoltageFile {
filename: "1234567890_1234567008_123.sub",
obs_id: 1234567000,
channel_identifier: 123,
gps_time_seconds: 1234567008,
},
TempVoltageFile {
filename: "1234567890_1234567008_125.sub",
obs_id: 1234567000,
channel_identifier: 125,
gps_time_seconds: 1234567008,
},
TempVoltageFile {
filename: "1234567000_1234567000_124.sub",
obs_id: 1234567000,
channel_identifier: 124,
gps_time_seconds: 1234567000,
},
];
let batches: HashMap<u64, VoltageFileBatch> = convert_temp_voltage_files(temp_voltage_files);
assert_eq!(
batches.len(),
2,
"Error - number of batches is incorrect: {} should be 2.",
batches.len()
);
assert_eq!(batches.get(&1234567000).unwrap().voltage_files.len(), 2);
assert_eq!(batches.get(&1234567008).unwrap().voltage_files.len(), 3);
}
#[test]
fn test_examine_voltage_files_valid() {
let metafits_filename = "test_files/1101503312_1_timestep/1101503312.metafits";
let context = MetafitsContext::new(metafits_filename, Some(MWAVersion::VCSMWAXv2))
.expect("Failed to create MetafitsContext");
let temp_dir = Builder::new()
.prefix("voltage_test")
.tempdir()
.expect("Failed to create temp dir");
let voltage_filenames: Vec<String> = vec![
String::from("1101503312_1101503312_123.sub"),
String::from("1101503312_1101503312_124.sub"),
String::from("1101503312_1101503320_123.sub"),
String::from("1101503312_1101503320_124.sub"),
];
let mut temp_filenames: Vec<String> = Vec::new();
for f in voltage_filenames.iter() {
temp_filenames.push(generate_test_voltage_file(&temp_dir, f, 2, 256).unwrap());
}
let result = examine_voltage_files(&context, &temp_filenames);
assert!(
result.is_ok(),
"examine_voltage_files failed {:?} - temp filenames: {:?}",
result,
temp_filenames
);
}
#[test]
fn test_examine_voltage_files_error_mismatched_sizes() {
let metafits_filename = "test_files/1101503312_1_timestep/1101503312.metafits";
let context = MetafitsContext::new(metafits_filename, Some(MWAVersion::VCSMWAXv2))
.expect("Failed to create MetafitsContext");
let temp_dir = Builder::new()
.prefix("voltage_test")
.tempdir()
.expect("Failed to create temp dir");
let voltage_filenames: Vec<String> = vec![
String::from("1101503312_1101503312_123.sub"),
String::from("1101503312_1101503312_124.sub"),
String::from("1101503312_1101503320_123.sub"),
String::from("1101503312_1101503320_124.sub"),
];
let mut temp_filenames: Vec<String> = Vec::new();
for f in voltage_filenames.iter() {
temp_filenames.push(generate_test_voltage_file(&temp_dir, f, 2, 256).unwrap());
}
temp_filenames.push(
generate_test_voltage_file(&temp_dir, "1101503312_1101503328_123.sub", 1, 256).unwrap(),
);
temp_filenames.push(
generate_test_voltage_file(&temp_dir, "1101503312_1101503328_124.sub", 1, 256).unwrap(),
);
let result = examine_voltage_files(&context, &temp_filenames);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
VoltageFileError::UnequalFileSizes
));
}
#[test]
fn test_examine_voltage_files_error_gpstime_gaps() {
let metafits_filename = "test_files/1101503312_1_timestep/1101503312.metafits";
let context = MetafitsContext::new(metafits_filename, Some(MWAVersion::VCSMWAXv2))
.expect("Failed to create MetafitsContext");
let temp_dir = Builder::new()
.prefix("voltage_test")
.tempdir()
.expect("Failed to create temp dir");
let voltage_filenames: Vec<String> = vec![
String::from("1101503312_1101503312_123.sub"),
String::from("1101503312_1101503312_124.sub"),
String::from("1101503312_1101503328_123.sub"),
String::from("1101503312_1101503328_124.sub"),
];
let mut temp_filenames: Vec<String> = Vec::new();
for f in voltage_filenames.iter() {
temp_filenames.push(generate_test_voltage_file(&temp_dir, f, 2, 256).unwrap());
}
let result = examine_voltage_files(&context, &temp_filenames);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
VoltageFileError::GpsTimeMissing {
expected: _,
got: _
}
));
}
#[test]
fn test_examine_voltage_files_error_file_not_found() {
let metafits_filename = "test_files/1101503312_1_timestep/1101503312.metafits";
let context = MetafitsContext::new(metafits_filename, Some(MWAVersion::VCSMWAXv2))
.expect("Failed to create MetafitsContext");
let voltage_filenames: Vec<String> = vec![
String::from("test_files_invalid/1101503312_1101503312_123.sub"),
String::from("test_files_invalid/1101503312_1101503312_124.sub"),
String::from("test_files_invalid/1101503312_1101503320_123.sub"),
String::from("test_files_invalid/1101503312_1101503320_124.sub"),
];
let result = examine_voltage_files(&context, &voltage_filenames);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
VoltageFileError::VoltageFileError(_, _)
));
}