diff --git a/CHANGELOG.md b/CHANGELOG.md index 86be4dfb..4001f9e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ Versioning](https://semver.org/spec/v2.0.0.html). `solutions-apply`. ### Fixed +- Until now, `hyperdrive` only supported raw MWA data with a frequency + resolution of 10, 20 or 40 kHz. It now supports any resolution. - When reading from uvfits/measurement set, a metafits' dipole information was applied, but perhaps in the wrong order. Order checks are now in place, but tile names must be consistent between the metafits and uvfits/MS. diff --git a/src/vis_io/read/raw/error.rs b/src/vis_io/read/raw/error.rs index f79a5ca6..d890d7b1 100644 --- a/src/vis_io/read/raw/error.rs +++ b/src/vis_io/read/raw/error.rs @@ -22,9 +22,6 @@ pub(crate) enum RawReadError { #[error("All of this observation's coarse channels are deemed bad; cannot continue")] NoGoodCoarseChannels, - #[error("No fine-channel flags were specified, and no rule is in place for automatically flagging observations with a fine-channel resolution of {0} Hz")] - UnhandledFreqResolutionForFlags(u32), - #[error("The raw MWA data contains no timesteps")] NoTimesteps, diff --git a/src/vis_io/read/raw/mod.rs b/src/vis_io/read/raw/mod.rs index 97f24d70..dc0b2316 100644 --- a/src/vis_io/read/raw/mod.rs +++ b/src/vis_io/read/raw/mod.rs @@ -200,29 +200,11 @@ impl RawDataReader { } } - let flagged_fine_chans_per_coarse_chan: Vec = - // If the flags aren't specified, use the observation's fine-channel - // frequency resolution to set them. - match (metafits_context.corr_fine_chan_width_hz, is_mwax) { - // 10 kHz, 128 channels. - (10000, true) => vec![ - 0, 1, 2, 3, 4, 5, 6, 7, 120, 121, 122, 123, 124, 125, 126, 127, - ], - // Include the centre channel. - (10000, false) => vec![ - 0, 1, 2, 3, 4, 5, 6, 7, 64, 120, 121, 122, 123, 124, 125, 126, 127, - ], - - // 20 kHz, 64 channels. - (20000, true) => vec![0, 1, 2, 3, 60, 61, 62, 63], - (20000, false) => vec![0, 1, 2, 3, 32, 60, 61, 62, 63], - - // 40 kHz, 32 channels. - (40000, true) => vec![0, 1, 30, 31], - (40000, false) => vec![0, 1, 16, 30, 31], - - (f, _) => return Err(RawReadError::UnhandledFreqResolutionForFlags(f)), - }; + let flagged_fine_chans_per_coarse_chan = get_80khz_fine_chan_flags_per_coarse_chan( + metafits_context.corr_fine_chan_width_hz, + metafits_context.num_corr_fine_chans_per_coarse, + is_mwax, + ); let flagged_fine_chans = { let mut flagged_fine_chans = Vec::with_capacity( flagged_fine_chans_per_coarse_chan.len() * mwalib_context.num_coarse_chans, @@ -788,3 +770,25 @@ impl VisRead for RawDataReader { ) } } + +fn get_80khz_fine_chan_flags_per_coarse_chan( + fine_chan_width: u32, + num_fine_chans_per_coarse_chan: usize, + is_mwax: bool, +) -> Vec { + let mut flags = vec![]; + + // Any fractional parts are discarded, meaning e.g. if the resolution was + // 79kHz per channel, only 1 edge channel is flagged rather than 2. + let num_flagged_fine_chans_per_edge = (80000 / fine_chan_width) as usize; + for i in 0..num_flagged_fine_chans_per_edge { + flags.push(i); + flags.push(num_fine_chans_per_coarse_chan - 1 - i); + } + // Also put the centre channel in if this isn't an MWAX obs. + if !is_mwax { + flags.push(num_fine_chans_per_coarse_chan / 2); + } + flags.sort_unstable(); + flags +} diff --git a/src/vis_io/read/raw/tests.rs b/src/vis_io/read/raw/tests.rs index b8d9bac9..270da62c 100644 --- a/src/vis_io/read/raw/tests.rs +++ b/src/vis_io/read/raw/tests.rs @@ -931,6 +931,46 @@ fn test_mwaf_flags_cotter() { } } +#[test] +fn test_default_flags_per_coarse_chan() { + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(10000, 128, true), + &[0, 1, 2, 3, 4, 5, 6, 7, 120, 121, 122, 123, 124, 125, 126, 127] + ); + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(10000, 128, false), + &[0, 1, 2, 3, 4, 5, 6, 7, 64, 120, 121, 122, 123, 124, 125, 126, 127] + ); + + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(20000, 64, true), + &[0, 1, 2, 3, 60, 61, 62, 63] + ); + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(20000, 64, false), + &[0, 1, 2, 3, 32, 60, 61, 62, 63] + ); + + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(40000, 32, true), + &[0, 1, 30, 31] + ); + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(40000, 32, false), + &[0, 1, 16, 30, 31] + ); + + // Future proofing? + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(7200, 100, true), + &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] + ); + assert_eq!( + get_80khz_fine_chan_flags_per_coarse_chan(7200, 100, false), + &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] + ); +} + #[test] fn test_1090008640_calibration_quality() { let mut args = get_reduced_1090008640(false, false);