Skip to content

Bug: convert_gps_time float error #85

@bradyzp

Description

@bradyzp

Bug Report

Issue: convert_gps_time function (dgp/lib/time_utils.py) is returning a pandas TimeDelta with a floating point rounding error when using the 'datetime' format of convert_gps_time.

Relevant Module Versions

  • python == 3.6.2
  • numpy == 1.15.0
  • pandas == 0.23.3

Sample Output

df =  pd.read_csv('tests/sample_data/test_data.csv', engine='c')
df.columns = ['gravity', 'long_accel', ..., 'gps_week', 'gps_sow']
>>> df
          gravity  long_accel    ...     gps_week   gps_sow
0    27363.304837   30.766637    ...         1941  312030.8
1    31096.986723   30.953845    ...         1941  312030.9
2    35220.629838   31.162258    ...         1941  312031.0
3    39144.264894   31.388331    ...         1941  312031.1
4    42382.632122   31.624970    ...         1941  312031.2
5    44654.293734   31.850109    ...         1941  312031.3
6    45782.125209   32.048602    ...         1941  312031.4
7    45741.905658   32.216090    ...         1941  312031.5
>>> dt = convert_gps_time(df['gps_week'], df['gps_sow'], format='datetime')
>>> dt
0     2017-03-22 14:40:30.799999952
1     2017-03-22 14:40:30.900000095
2     2017-03-22 14:40:31.000000000
3     2017-03-22 14:40:31.099999905
4     2017-03-22 14:40:31.200000048
5     2017-03-22 14:40:31.299999952
6     2017-03-22 14:40:31.400000095
7     2017-03-22 14:40:31.500000000

It seems that for any sub-second value other than .0 or .5 a rounding error is being introduced by pandas to_timedelta function.
The specific line where the issue is introduced appears to be:

 elif format == 'datetime':
        return datetime(1970, 1, 1) + pd.to_timedelta(timestamp, unit='s')

Resolution

A naive fix is to simply use .round('ns') on the pd.to_timedelta result, this seems to fix the issue, rounding off the ~50 ns of error on the timedelta result, testing will need to be done to verify this doesn't impact data ingestion.
e.g.

 elif format == 'datetime':
        return datetime(1970, 1, 1) + pd.to_timedelta(timestamp, unit='s').apply(lambda td: td.round('ns'))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions