Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix buggy time conversion code #549

Merged
merged 2 commits into from
Oct 14, 2019
Merged

Conversation

aarchiba
Copy link
Contributor

@aarchiba aarchiba commented Oct 6, 2019

Update: essentially all precision problems intrinsic to PINT are under control at the nanosecond level or better, as far as I know and hypothesis can find. The remaining xfail tests are almost all pointing out upstream problems, whether due to astropy bugs or ERFA limitations. The astropy bugs are fixed in the current 3.2.2 release and should be fixed in the final 2.0.16 release which will appear in a few months. (2.0.15 was meant to be the final if-theres-a-bug-tough-luck python2 release but in light of the bug revealed here and other worries the mainainers decided to delay stopping bug fixes.)

The patch also dramatically simplifies the precision-conversion functions in pint.utils by providing new astropy.time.Time formats mjd_string and pulsar_mjd_string that read and write full-precision strings, as well as mjd_long and pulsar_mjd_long that write but do not read long doubles (reading long doubles is prevented by a frustrating limitation of astropy, under discussion for removal in astropy 4). Conversion of existing code to replace time_to_* and time_from_* with the new formats has not been carried out yet.

Was:

We have a number of severe time conversion problems, producing errors of, in some cases, 60s or a day. Others may just be off by a microsecond. I am fixing them where I can but there are a number I have not tracked down yet. This PR tracks those with xfail statements; use

pytest --runxfail -v tests/test_precision.py

to see the damage.

Most but not all of the problems center around days with leap seconds, and some of the problems appear to originate from within our pulsar_mjd implementation (possibly but I hope not from within ERFA).

# There is: erfa.d2tf. Unfortunately it takes a "number of
# digits" argument and returns some kind of bogus
# fractional-part-as-an-integer thing.
# Worse, it fails to provide nanosecond accuracy.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aarchiba So do you think this is a SOFA/ERFA bug? Since I'm on the SOFA board, if you can give me a simply example of the numerical issues, it will get fixed. We just did that over the last year for another small issue or two.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally sure whether I'm interpreting the ERFA output correctly, but if you want I can put together some tests that give astropy._erfa some significant exercise and report any bugs I come up with. Translating them back into C to be sure they're really SOFA bugs and not somewhere in the wrappers would be... more work.

Is there documentation of the level of accuracy I should expect from various ERFA/SOFA routines, over what range of inputs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of SOFA documentation. And given that the times are stored internally with two doubles, the intent is to have very high precision where possible -- certainly much better than a microsecond. I'd have to dig around to see what is expected overall. But if there are definite instabilities at the ns level -- especially if they can be fixed easily, then those should definitely be fixed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, well, a quick check shows that a roundtrip through d2tf and tf2d gives nanosecond accuracy for ndp=9 but does not give nanosecond, or even ten-nanosecond, accuracy for higher ndp. No errors or warnings are emitted. See 3cc6a8a.

@aarchiba aarchiba changed the title WIP: Fix buggy time conversion code Fix buggy time conversion code Oct 8, 2019
@aarchiba
Copy link
Contributor Author

aarchiba commented Oct 9, 2019

Travis has gotten grumpy again. Even apt-get is failing to pull stuff across the network. At least it's usually fairly obvious (! instead of x next to runs).

@aarchiba
Copy link
Contributor Author

aarchiba commented Oct 9, 2019

TODOs:

  • mjd_decimal and pulsar_mjd_decimal
  • day_frac_longdouble? Does day_frac work for longdoubles?
  • can't get rid of time_from_longdouble, but maybe use day_frac_longdouble?
  • TimeDelta formats "mjd_long", "mjd_decimal", and "mjd_string"; need care as they could be used on nanoseconds up to decades

DONEs:

  • Convert code base to eliminate time_to functions
  • Get rid of time_from_mjd_string

There are other places precision could be mishandled - Parameters that are supposed to handle long doubles spring to mind - but I think that this is enough for one patch.

All remaining known precision problems originate elsewhere.
The only PINT precision bug remaining is that ERFA behaves badly when
handed ancient MJDs. This could be fixed by array hackery that treats
any old elements as not being pulsar_mjd; there are no leap seconds
back then anyway. But writing this in a reliable way for
arbitrary-dimensional arrays is not trivial, and the result would be of
purely completionist value.
@aarchiba aarchiba merged commit 0765252 into nanograv:master Oct 14, 2019
@aarchiba aarchiba deleted the precision-testing branch October 14, 2019 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants