Skip to content

Commit

Permalink
Merge pull request #8308 from pllim/iers-mirror
Browse files Browse the repository at this point in the history
Introduce IERS_A_URL_MIRROR for when IERS_A_URL is down
  • Loading branch information
mhvk authored and bsipocz committed Dec 24, 2018
1 parent 165163f commit 809c0d4
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -66,6 +66,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 @@ -31,13 +31,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 @@ -98,6 +99,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 @@ -365,8 +369,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 @@ -561,27 +565,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 @@ -633,13 +650,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 @@ -648,10 +676,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 @@ -179,15 +179,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

0 comments on commit 809c0d4

Please sign in to comment.