可下载数据管理 (astropy.utils.data#

介绍#

Astropy的许多工具都使用非常大的数据集(例如。, solar_system_ephemeris )或定期更新(例如。, IERS_B )或两者兼而有之(例如。, IERS_A ). 这种数据在天文学中相当普遍,这些数据是在网上提供的权威数据,可能会不时更新。因此,Astropy项目提供了一些处理这些数据的工具。

The primary tool for this is the astropy cache. This is a repository of downloaded data, indexed by the URL where it was obtained. The tool download_file and various other things built upon it can use this cache to request the contents of a URL, and (if they choose to use the cache) the data will only be downloaded if it is not already present in the cache. The tools can be instructed to obtain a new copy of data that is in the cache but has been updated online.

这个 astropy 缓存存储在一个集中的地方(在Linux机器上默认是这样的 $HOME/.astropy/cache配置系统 (astropy.config ) 更多细节)。您可以检查它在您的机器上的位置:

>>> import astropy.config.paths
>>> astropy.config.paths.get_cache_dir()  
'/home/burnell/.astropy/cache'

这种集中化意味着缓存是持久的,并且在所有缓存之间共享 astropy 在任何virtualenv中由一个用户在一台计算机上运行(如果您的主目录在多台计算机之间共享,可能会更多)。这会大大加速 astropy 操作并减少服务器上的负载,如IER的服务器,这些服务器不是为繁重的Web流量而设计的。如果您发现缓存中有损坏或过期的数据,您可以删除一个条目或用 clear_download_cache .

缓存目录中的文件是根据其URL的加密哈希命名的(目前是MD5,因此原则上恶意实体可能会导致冲突,尽管这样做所带来的安全风险最多是微不足道的)。这些文件的修改时间通常表明它们最后一次从Internet下载的时间。

在Astropy中使用#

在大多数情况下,您可以忽略缓存机制而依赖 astropy 以便在需要时获得正确的数据。例如,精确的时间转换和天空位置需要由IERS测量的地球自转表。桌子 IERS_Auto 为许多此类计算提供基础设施。它提供了可用的地球自转参数,如果你要求的时间比它的表格所涵盖的时间要晚,它会从IERS下载更新的表格。例如,询问UT1的时间(反映地球自转不规则的时间尺度)可能会触发IERS数据的下载:

>>> from astropy.time import Time
>>> Time.now().ut1  
Downloading https://maia.usno.navy.mil/ser7/finals2000A.all
|============================================| 3.2M/3.2M (100.00%)         1s
<Time object: scale='ut1' format='datetime' value=2019-09-22 08:39:03.812731>

但第二次运行不需要任何新的下载:

>>> Time.now().ut1  
<Time object: scale='ut1' format='datetime' value=2019-09-22 08:41:21.588836>

一些数据也可以从 Astropy data server 或在内部使用 astropy 或者为了你的方便。这些可以通过 get_pkg_data_* 功能::

>>> from astropy.utils.data import get_pkg_data_contents
>>> print(get_pkg_data_contents("coordinates/sites-un-ascii"))  
# these are all mappings from the name in sites.json (which is ASCII-only) to the "true" unicode names
TUBITAK->TÜBİTAK

备注

有时,从使用TLS/SSL保护的互联网资源下载文件时,您可能会收到有关证书验证错误的异常。通常,这表示Python找不到最新的 root certificates 在你的系统上。这在Windows上尤其常见。此问题通常可以通过安装 certifi 包,如果可用,Astropy将使用该包来验证远程连接。在极少数情况下,如果远程服务器配置错误(例如,证书过期),证书验证仍可能失败。在这种情况下,您可以将 allow_insecure=True 参数为 download_file() 以允许下载并显示警告(除非您了解 potential risks )。

从外部使用Astropy#

用户 astropy 也可以利用 astropy 的缓存和下载机制。在最简单的形式中,这相当于使用 download_filecache=True 参数从缓存中获取数据(如果数据存在):

>>> from astropy.utils.iers import IERS_B_URL, IERS_B
>>> from astropy.utils.data import download_file
>>> IERS_B.open(download_file(IERS_B_URL, cache=True))["year","month","day"][-3:]  
 <IERS_B length=3>
 year month  day
int64 int64 int64
----- ----- -----
 2019     8     4
 2019     8     5
 2019     8     6

如果用户希望将缓存更新到数据的更新版本(请注意,这里的数据已经是最新的;用户必须自己决定何时获取新版本),则可以使用 cache='update' 论点:

>>> IERS_B.open(download_file(IERS_B_URL,
...                           cache='update')
... )["year","month","day"][-3:]  
Downloading http://hpiers.obspm.fr/iers/eop/eopc04/eopc04_IAU2000.62-now
|=========================================| 3.2M/3.2M (100.00%)         0s
<IERS_B length=3>
 year month  day
int64 int64 int64
----- ----- -----
 2019     8    18
 2019     8    19
 2019     8    20

如果他们担心主数据源可能过载或不可用,则可以使用 sources 参数提供尝试从中下载的源列表,顺序为。这不需要包括原始来源。不管怎样,数据都将存储在缓存中请求的原始URL下:

>>> f = download_file("ftp://ssd.jpl.nasa.gov/pub/eph/planets/bsp/de405.bsp",
...     cache=True,
...     sources=['https://data.nanograv.org/static/data/ephem/de405.bsp',
...              'ftp://ssd.jpl.nasa.gov/pub/eph/planets/bsp/de405.bsp'])  
Downloading ftp://ssd.jpl.nasa.gov/pub/eph/planets/bsp/de405.bsp from https://data.nanograv.org/static/data/ephem/de405.bsp
|========================================|  65M/ 65M (100.00%)        19s

缓存管理#

缓存可能会变得不方便,因为缓存中的数据会变得很大。虽然它只是磁盘上的一个目录,但每个文件都应该表示一个URL的内容,而且许多URL在磁盘文件名上是不可接受的(例如,包含诸如“:”和“~”)之类的麻烦字符。有理由担心 astropy 同时访问缓存的进程可能会导致缓存损坏。因此,数据存储在以URL的哈希命名的子目录中,并且以一种抵抗并发问题的方式处理写访问。因此,使用 data .

如果你的缓存行为异常,你可以使用 check_download_cache 检查缓存内容并在发现异常时引发异常。如果单个文件不受欢迎或损坏,可以通过调用 clear_download_cache 参数是从中获取的URL、下载文件的文件名或其内容的哈希值。如果缓存严重损坏, clear_download_cache 如果没有参数,只需删除整个目录,释放空间并删除任何不一致的数据。当然,如果使用这些工具中的任何一个删除数据,则当前使用该数据的任何进程都可能被中断(或者,在Windows下,在这些进程终止之前,可能无法删除缓存)。所以使用 clear_download_cache 小心点。

要检查缓存占用的总空间,请使用 cache_total_size . 缓存的内容可以用 get_cached_urls ,并且可以使用测试缓存中是否存在特定的URL is_url_in_cache . 可以使用执行更一般的操作 cache_contents ,返回 dict 将URL映射到其内容的磁盘文件名。

如果要将缓存传输到另一台计算机,或保留其内容供以后使用,可以使用函数 export_download_cache 生成一个ZIP文件,列出部分或全部缓存内容,以及 import_download_cache 加载 astropy 从这样一个ZIP文件中缓存。

Astropy缓存已经改变了格式——一次是在Python2到Python3的转换中,另一次是在Astropy 4.0.2版本之前,为了解决某些计算集群上出现的一些并发问题。缓存的每个版本都在其自己的子目录中,因此旧版本不会干扰新版本,反之亦然,但它们的内容不会被此版本使用,也不会被清除 clear_download_cache . 要删除这些旧的缓存目录,可以运行:

>>> from shutil import rmtree
>>> from os.path import join
>>> from astropy.config.paths import get_cache_dir
>>> rmtree(join(get_cache_dir(), 'download', 'py2'), ignore_errors=True)  
>>> rmtree(join(get_cache_dir(), 'download', 'py3'), ignore_errors=True)  

使用Astropy与有限或没有互联网接入#

你可能想用 astropy 在严格的防火墙后面的望远镜控制机器上。或者您可能正在 astropy 服务器,并希望避免在每个架构的每一个请求上都重击天文服务器。或者你可能无法访问美国政府或军方的网络服务器。无论是哪种情况,你都需要避免 astropy 需要来自互联网的数据。对于这个问题,目前还没有简单而完整的解决方案,但是有一些工具可以帮助解决。

项目所依赖的外部数据将取决于 astropy 你怎么用的。最普遍的解决方案是使用一台可以访问互联网的计算机来运行一个计算版本,该版本会将您需要的所有数据文件包括足够更新的文件版本,如定期更新的IERS数据。然后,一旦这个连接的机器上的缓存加载了所有必要的东西,就可以通过任何可用的方法将缓存内容传输到目标计算机,无论是通过中间计算机、便携式磁盘驱动器还是其他工具进行复制。缓存目录本身在具有相同UNIX风格的计算机之间具有一定的可移植性;如果您能够说服您的CI系统在两次运行之间缓存目录,这就足够了。但是,为了提高可移植性,您可以简单地使用 export_download_cacheimport_download_cache ,它是可移植的,允许将文件添加到现有的缓存目录中。

如果您的应用程序特别需要IERS数据,您可以下载适当的IERS表,包括适当的时间跨度,任何您觉得方便的方法。然后可以将此文件加载到应用程序中,并使用结果表而不是 IERS_Auto . 实际上,IERB表足够小,可以绑定一个版本(不一定是最新版本) astropy 作为 astropy.utils.iers.IERS_B_FILE . 使用一个特定的非自动表还有一个优点,可以让您准确地控制应用程序正在使用的IERS数据的版本。另请参见 脱机工作 .

如果您的问题出在某些特定的服务器上,即使是它们 astropy 通常使用,如果您可以准确地预测需要哪些文件(或在 astropy 无法获取这些文件)并使这些文件在其他地方可用,您可以使用 download_filesources 参数设置为您知道的工作位置。您也可以设置 sources 以确保 download_file 根本不尝试使用互联网。

如果你有一个特别的网址给你带来麻烦,你可以用其他工具下载它(例如。, wget ),可能在另一台计算机上,然后使用 import_file_to_cache .

天文数据和星团#

天文计算通常需要在具有共享主文件系统的不同计算机上使用大量不同的进程。这可能造成某些复杂性。特别是,如果许多不同的进程试图同时下载一个文件,这可能会使服务器过载或触发安全系统。对主目录的并行访问也会触发Astropy数据缓存中的并发问题,尽管我们已经尝试将这些问题最小化。因此,我们建议以下准则:

  • 执行以下操作之一:

    • 编写一个简单的脚本 astropy.utils.iers.conf.auto_download = True 然后访问代码所需的所有缓存资源,包括源名称查找和IER表。不时地在head节点上运行它(频繁到足以超过超时时间 astropy.utils.iers.conf.auto_max_age ,以确保所有数据都是最新的。

    • astropy.utils.iers.conf.auto_download = False 在您的代码和集合中 astropy.utils.iers.conf.iers_degraded_accuracy 到任何一个 'warn''ignore' 。这可以防止在时间转换超出可用(本地)IERS数据范围时发生的正常异常。 WARNING :仅当您的应用程序不需要全精度时间转换时才使用此选项。

  • 创建一个Astropy配置文件(请参见 配置系统 (astropy.config ) )那就定了 astropy.utils.iers.conf.auto_download = False 这样工人作业就不会突然发现一个过时的表,并疯狂地试图下载它。

  • (可选)在此文件中,设置 astropy.utils.data.conf.allow_internet = False 防止试图从工作节点下载任何文件;如果执行此操作,则需要在执行实际下载的脚本中重写此设置。

现在,您的worker节点不需要从Internet上获取任何信息,并且所有节点都应该平稳运行。