Skip to content

Commit

Permalink
fix uvfits reading quantization issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Dev McElhinney committed Apr 7, 2022
1 parent 356ef3f commit f0cf606
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 34 deletions.
11 changes: 6 additions & 5 deletions src/data_formats/uvfits/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::*;
use crate::{
context::ObsContext,
data_formats::{metafits, InputData, ReadInputDataError},
time::round_hundredths_of_a_second_duration,
time::quantize_duration,
};
use mwa_hyperdrive_beam::Delays;
use mwa_hyperdrive_common::{log, marlu, mwalib, ndarray};
Expand Down Expand Up @@ -207,16 +207,17 @@ impl UvfitsReader {
} else {
Epoch::from_jde_tai(metadata.jd_zero)
};

// the number of nanoseconds to quantize to.
let q = 10_000_000.;

let (all_timesteps, timestamps): (Vec<usize>, Vec<Epoch>) = metadata
.jd_frac_timestamps
.iter()
.enumerate()
.map(|(i, &frac)| {
let jd_offset = Duration::from_f64(frac as f64, Unit::Day);
(
i,
jd_zero + round_hundredths_of_a_second_duration(jd_offset),
)
(i, jd_zero + quantize_duration(jd_offset, q))
})
.unzip();
// TODO: Determine flagging!
Expand Down
19 changes: 11 additions & 8 deletions src/data_formats/uvfits/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,16 +402,19 @@ fn test_timestep_reading() {
UvfitsReader::new::<&PathBuf, &PathBuf>(&vis_path.clone(), None, &mut Delays::None)
.unwrap();
let uvfits_ctx = uvfits_reader.get_obs_context();
dbg!(&uvfits_ctx
.timestamps
.iter()
.map(|&t| t.as_gregorian_utc())
.collect::<Vec<_>>());

let expected_timestamps = (0..num_timesteps)
.map(|t| Epoch::from_gpst_seconds((obsid + t) as f64 + 0.5))
.collect::<Vec<_>>();
assert_eq!(
uvfits_ctx.timestamps,
(0..num_timesteps)
.map(|t| Epoch::from_gpst_seconds((obsid + t) as f64 + 0.5))
uvfits_ctx
.timestamps
.iter()
.map(|t| t.as_gpst_seconds())
.collect::<Vec<_>>(),
expected_timestamps
.iter()
.map(|t| t.as_gpst_seconds())
.collect::<Vec<_>>()
);
}
32 changes: 11 additions & 21 deletions src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use hifitime::Epoch;

use mwa_hyperdrive_common::hifitime::{self, Duration};
use mwa_hyperdrive_common::hifitime::{self, Duration, Unit};

/// Some timestamps may be read in ever so slightly off from their true values
/// because of float errors. This function checks if a supplied [Epoch], when
Expand All @@ -24,17 +24,11 @@ pub(crate) fn round_hundredths_of_a_second(e: Epoch) -> Epoch {
}
}

/// Some timestamps may be read in ever so slightly off from their true values
/// because of float errors. This function checks if a supplied [Epoch], when
/// represented as GPS seconds, is really close to a neat value in the
/// hundredths. If so, the value is rounded and returned.
///
/// e.g. The GPS time 1090008639.999405 should be 1090008634.0. Other examples
/// of usage are in the tests alongside this function.
pub(crate) fn round_hundredths_of_a_second_duration(e: Duration) -> Duration {
let (centuries, nanos) = e.to_parts();
let hundredth_ns = 10_000_000;
Duration::from_parts(centuries, (nanos / hundredth_ns) * hundredth_ns)
/// Quantize a duration to the nearest multiple of q nanoseconds
pub(crate) fn quantize_duration(d: Duration, q_nanos: f64) -> Duration {
let d_nanos = d.in_unit(Unit::Nanosecond);
let d_nanos = (d_nanos / q_nanos).round() * q_nanos;
Duration::from_f64(d_nanos, Unit::Nanosecond)
}

#[cfg(test)]
Expand Down Expand Up @@ -76,17 +70,13 @@ mod tests {
fn test_round_duration() {
let half_day = Duration::from_f64(0.5, Unit::Day);
let millis = Duration::from_f64(1., Unit::Millisecond);
assert_eq!(
half_day,
round_hundredths_of_a_second_duration(half_day + millis)
);
assert_eq!(
half_day,
round_hundredths_of_a_second_duration(half_day + 4 * millis)
);
let quanta = 10_000_000.;
assert_eq!(half_day, quantize_duration(half_day + millis, quanta));
assert_eq!(half_day, quantize_duration(half_day + 4 * millis, quanta));
assert_eq!(half_day, quantize_duration(half_day - 4 * millis, quanta));
assert_eq!(
half_day + 10 * millis,
round_hundredths_of_a_second_duration(half_day + 11 * millis)
quantize_duration(half_day + 11 * millis, quanta)
);
}
}

0 comments on commit f0cf606

Please sign in to comment.