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

Introduce IERS_A_URL_MIRROR for when IERS_A_URL is down #8308

Merged
merged 3 commits into from Dec 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -1782,6 +1782,9 @@ astropy.units
astropy.utils
^^^^^^^^^^^^^

- Fix failures caused by IERS_A_URL being unavailable by introducing
IERS_A_URL_MIRROR. [#8308]

astropy.visualization
^^^^^^^^^^^^^^^^^^^^^

Expand Down
59 changes: 44 additions & 15 deletions astropy/utils/iers/iers.py
Expand Up @@ -29,13 +29,14 @@
'IERS', 'IERS_B', 'IERS_A', 'IERS_Auto',
'FROM_IERS_B', 'FROM_IERS_A', 'FROM_IERS_A_PREDICTION',
'TIME_BEFORE_IERS_RANGE', 'TIME_BEYOND_IERS_RANGE',
'IERS_A_FILE', 'IERS_A_URL', 'IERS_A_README',
'IERS_A_FILE', 'IERS_A_URL', 'IERS_A_URL_MIRROR', 'IERS_A_README',
'IERS_B_FILE', 'IERS_B_URL', 'IERS_B_README',
'IERSRangeError', 'IERSStaleWarning']

# IERS-A default file name, URL, and ReadMe with content description
IERS_A_FILE = 'finals2000A.all'
IERS_A_URL = 'http://maia.usno.navy.mil/ser7/finals2000A.all'
IERS_A_URL_MIRROR = 'http://toshi.nofs.navy.mil/ser7/finals2000A.all'
IERS_A_README = get_pkg_data_filename('data/ReadMe.finals2000A')

# IERS-B default file name, URL, and ReadMe with content description
Expand Down Expand Up @@ -96,6 +97,9 @@ class Conf(_config.ConfigNamespace):
iers_auto_url = _config.ConfigItem(
IERS_A_URL,
'URL for auto-downloading IERS file data.')
iers_auto_url_mirror = _config.ConfigItem(
IERS_A_URL_MIRROR,
'Mirror URL for auto-downloading IERS file data.')
remote_timeout = _config.ConfigItem(
10.0,
'Remote timeout downloading IERS file data (seconds).')
Expand Down Expand Up @@ -399,8 +403,8 @@ class IERS_A(IERS):
Notes
-----
The IERS A file is not part of astropy. It can be downloaded from
``iers.IERS_A_URL``. See ``iers.__doc__`` for instructions on how to use
it in ``Time``, etc.
``iers.IERS_A_URL`` or ``iers.IERS_A_URL_MIRROR``. See ``iers.__doc__``
for instructions on use in ``Time``, etc.
"""

iers_table = None
Expand Down Expand Up @@ -621,27 +625,40 @@ def open(cls):
cls.iers_table = IERS.open()
return cls.iers_table

all_urls = (conf.iers_auto_url, conf.iers_auto_url_mirror)

if cls.iers_table is not None:

# If the URL has changed, we need to redownload the file, so we
# should ignore the internally cached version.

if cls.iers_table.meta.get('data_url') == conf.iers_auto_url:
if cls.iers_table.meta.get('data_url') in all_urls:
return cls.iers_table

try:
filename = download_file(conf.iers_auto_url, cache=True)
except Exception as err:
dl_success = False
err_list = []

for url in all_urls:
try:
filename = download_file(url, cache=True)
except Exception as err:
err_list.append(str(err))
else:
dl_success = True
break

if not dl_success:
# Issue a warning here, perhaps user is offline. An exception
# will be raised downstream when actually trying to interpolate
# predictive values.
warn(AstropyWarning('failed to download {}, using local IERS-B: {}'
.format(conf.iers_auto_url, str(err))))
.format(' and '.join(all_urls),
';'.join(err_list)))) # noqa
cls.iers_table = IERS.open()
return cls.iers_table

cls.iers_table = cls.read(file=filename)
cls.iers_table.meta['data_url'] = str(conf.iers_auto_url)
cls.iers_table.meta['data_url'] = str(url)

return cls.iers_table

Expand Down Expand Up @@ -693,13 +710,24 @@ def _refresh_table_as_needed(self, mjd):
raise ValueError('IERS auto_max_age configuration value must be larger than 10 days')

if (max_input_mjd > predictive_mjd and
now_mjd - predictive_mjd > auto_max_age):
now_mjd - predictive_mjd > auto_max_age):

all_urls = (conf.iers_auto_url, conf.iers_auto_url_mirror)
dl_success = False
err_list = []

# Get the latest version
try:
clear_download_cache(conf.iers_auto_url)
filename = download_file(conf.iers_auto_url, cache=True)
except Exception as err:
for url in all_urls:
try:
clear_download_cache(url)
filename = download_file(url, cache=True)
except Exception as err:
err_list.append(str(err))
else:
dl_success = True
break

if not dl_success:
# Issue a warning here, perhaps user is offline. An exception
# will be raised downstream when actually trying to interpolate
# predictive values.
Expand All @@ -708,10 +736,11 @@ def _refresh_table_as_needed(self, mjd):
'not covered by the available IERS file. See the '
'"IERS data access" section of the astropy documentation '
'for additional information on working offline.'
.format(conf.iers_auto_url, str(err))))
.format(' and '.join(all_urls), ';'.join(err_list))))
return

new_table = self.__class__.read(file=filename)
new_table.meta['data_url'] = str(url)

# New table has new values?
if new_table['MJD'][-1] > self['MJD'][-1]:
Expand Down
19 changes: 10 additions & 9 deletions astropy/utils/iers/tests/test_iers.py
Expand Up @@ -200,15 +200,16 @@ def test_interpolate_error_formatting(self):
IERS_Auto._check_interpolate_indices() is formatted correctly.
"""
with iers.conf.set_temp('iers_auto_url', self.iers_a_url_1):
with iers.conf.set_temp('auto_max_age', self.ame):
with pytest.raises(ValueError) as err:
iers_table = iers.IERS_Auto.open()
with warnings.catch_warnings():
# Ignoring this if it comes up -- IERS_Auto predictive
# values are older than 30.0 days but downloading the
# latest table did not find newer values
warnings.simplefilter('ignore', iers.IERSStaleWarning)
iers_table.ut1_utc(self.t.jd1, self.t.jd2)
with iers.conf.set_temp('iers_auto_url_mirror', self.iers_a_url_1):
with iers.conf.set_temp('auto_max_age', self.ame):
with pytest.raises(ValueError) as err:
iers_table = iers.IERS_Auto.open()
with warnings.catch_warnings():
# Ignoring this if it comes up -- IERS_Auto predictive
# values are older than 30.0 days but downloading the
# latest table did not find newer values
warnings.simplefilter('ignore', iers.IERSStaleWarning)
iers_table.ut1_utc(self.t.jd1, self.t.jd2)
assert str(err.value) == iers.INTERPOLATE_ERROR.format(self.ame)

def test_auto_max_age_none(self):
Expand Down
5 changes: 4 additions & 1 deletion docs/utils/iers.rst
Expand Up @@ -81,6 +81,9 @@ of the automatic IERS downloading:
iers_auto_url:
URL for auto-downloading IERS file data

iers_auto_url_mirror:
Mirror URL for auto-downloading IERS file data.

remote_timeout:
Remote timeout downloading IERS file data (seconds)

Expand Down Expand Up @@ -156,7 +159,7 @@ part of astropy and can be used for transformations. For example::
'2010-01-01 00:00:00.114'

Instead of local copies of IERS files, one can also download them, using
``iers.IERS_A_URL`` and ``iers.IERS_B_URL``::
``iers.IERS_A_URL`` (or ``iers.IERS_A_URL_MIRROR``) and ``iers.IERS_B_URL``::

>>> iers_a = iers.IERS_A.open(iers.IERS_A_URL) # doctest: +SKIP

Expand Down