Skip to content

Commit

Permalink
Fix raw data timestamp bug.
Browse files Browse the repository at this point in the history
For some obsids (large ones?), treating an mwalib GPS time as a float, adding
half an integration time and dividing by 1000 to get units of seconds was enough
to introduce a float precision issue. hifitime allows us to use its types from
nanoseconds, so we keep things as integers and fix these issues for good. This
commit also changes a couple of other potentially-problematic bits of code.
  • Loading branch information
cjordan committed Sep 23, 2023
1 parent b2001f7 commit 475613e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
now read properly.
- RTS source lists with multiple SHAPELET components are now removed properly
(not to be confused with the favoured SHAPELET2 component type).
- Some MWA raw data observations were not handled correctly due to a
floating-point error.

### Changed
- The performance of CPU visibility modelling has been dramatically improved.
Expand Down
6 changes: 5 additions & 1 deletion src/cli/vis_utils/simulate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,11 @@ impl VisSimParams {
let time_res = Duration::from_seconds(*time_res);
let timestamps = {
let mut timestamps = Vec::with_capacity(*num_timesteps);
let start = Epoch::from_gpst_seconds(metafits.sched_start_gps_time_ms as f64 / 1e3)
let start_ns = metafits
.sched_start_gps_time_ms
.checked_mul(1_000_000)
.expect("does not overflow u64");
let start = Epoch::from_gpst_nanoseconds(start_ns)
+ time_res / 2
+ Duration::from_seconds(*time_offset);
for i in 0..*num_timesteps {
Expand Down
35 changes: 25 additions & 10 deletions src/io/read/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,24 @@ impl RawDataReader {
}
}

let time_res = Duration::from_milliseconds(metafits_context.corr_int_time_ms as f64);
let time_res = {
let int_time_ns = i128::from(metafits_context.corr_int_time_ms)
.checked_mul(1_000_000)
.expect("does not overflow i128");
Duration::from_total_nanoseconds(int_time_ns)
};

let all_timesteps = Vec1::try_from_vec(mwalib_context.provided_timestep_indices.clone())
.map_err(|_| RawReadError::NoTimesteps)?;
let timestamps: Vec<Epoch> = mwalib_context
.timesteps
.iter()
.map(|t| {
Epoch::from_gpst_seconds(
(t.gps_time_ms + metafits_context.corr_int_time_ms / 2) as f64 / 1e3,
)
let gps_nanoseconds = t
.gps_time_ms
.checked_mul(1_000_000)
.expect("does not overflow u64");
Epoch::from_gpst_nanoseconds(gps_nanoseconds) + time_res / 2
})
.collect();
let timestamps = Vec1::try_from_vec(timestamps).map_err(|_| RawReadError::NoTimesteps)?;
Expand Down Expand Up @@ -359,12 +366,20 @@ impl RawDataReader {
// cotter has a nasty bug that can cause the start time listed in
// mwaf files to be offset from data HDUs. Warn the user if this is
// noticed.
let data_start =
Epoch::from_gpst_seconds(mwalib_context.common_start_gps_time_ms as f64 / 1e3)
+ time_res / 2;
let data_end =
Epoch::from_gpst_seconds(mwalib_context.common_end_gps_time_ms as f64 / 1e3)
+ time_res / 2;
let data_start = {
let gps_nanoseconds = mwalib_context
.common_start_gps_time_ms
.checked_mul(1_000_000)
.expect("does not overflow u64");
Epoch::from_gpst_nanoseconds(gps_nanoseconds) + time_res / 2
};
let data_end = {
let gps_nanoseconds = mwalib_context
.common_end_gps_time_ms
.checked_mul(1_000_000)
.expect("does not overflow u64");
Epoch::from_gpst_nanoseconds(gps_nanoseconds) + time_res / 2
};
let flags_start = f.start_time;
let flags_end = flags_start + f.num_time_steps as f64 * time_res;
let diff = (flags_start - data_start).to_seconds() / time_res.to_seconds();
Expand Down

0 comments on commit 475613e

Please sign in to comment.