从云托管的FITS文件中获取子集#

Astropy支持从存储在云中的FITS文件中提取数据。具体地说, astropy.io.fits.open 函数接受 use_fsspecfsspec_kwargs 参数,这些参数允许使用 fsspec 包裹。

fsspec 是Astropy的一个可选依赖项,它支持从一系列远程和分布式存储后端读取文件,如Amazon和Google Cloud Storage。本章解释了它的用法。

备注

本章中的示例需要 fsspec 它是Astropy的可选依赖项。看见 安装 astropy 有关安装可选依赖项的详细信息,请参阅。

子集适合HTTP Web服务器上托管的文件#

的常见用例 fsspec is to read subsets of FITS data from a web server which supports serving partial files via the Range Requests HTTP协议的功能。大多数Web服务器都支持以这种方式提供部分文件。

例如,假设您想要从哈勃太空望远镜获取的大图像中检索数据,该图像位于以下url:

>>> # Download link for a large Hubble archive image (213 MB)
>>> url = "https://mast.stsci.edu/api/v0.1/Download/file/?uri=mast:HST/product/j8pu0y010_drc.fits"

可以通过将url传递给 astropy.io.fits.open 。默认情况下,Astropy会在打开文件之前将整个文件下载到本地磁盘。这对于小文件很有效,但对于大文件往往需要大量的时间和内存。

您可以通过传递参数来提高大文件的性能 use_fsspec=Trueopen 。这将使Astropy使用 fsspec 仅下载FITS文件的必要部分。例如:

>>> from astropy.io import fits
...
>>> # `fits.open` will download the primary header
>>> with fits.open(url, use_fsspec=True) as hdul:  
...
...     # Download a single header
...     header = hdul[1].header
...
...     # Download a single data array
...     image = hdul[1].data
...
...     # Download a 10-by-20 pixel cutout by using .section
...     cutout = hdul[2].section[10:20, 30:50]

与下载整个文件所需的时间和内存相比,上面的示例需要更少的时间和内存。这是因为 fsspec 能够利用两个 lazy data loading Astropy中提供的功能:

  1. 这个 lazy_load_hdus 参数由提供 open 负责按需加载HDU标头和数据属性,而不是一次读取所有HDU。此参数设置为 True 默认情况下。不需要显式传递它,除非您在 配置系统 (astropy.config )

  2. 这个 ImageHDU.sectionCompImageHDU.section 属性允许将数据数组的子集读入内存,而无需下载整个图像或多维数据集。请参阅 数据段 有关更多详细信息,请参阅部分文档。

有关在处理远程文件时获得良好性能的其他提示,请参阅 为远程FITS文件设置子集的性能改进提示 这一页再往下看。

备注

这个 ImageHDU.sectionCompImageHDU.section 该功能仅对未进行外部压缩的文件有效(例如 .fits.gz 文件)。使用内部磁贴压缩压缩的文件应该可以正常工作。使用 .section 将导致下载整个FITS文件。

子集适合Amazon S3云存储中托管的文件#

上例中使用的FITS文件碰巧也可以通过Amazon云存储获得,该文件存储在 public S3 bucket 在以下位置:

>>> s3_uri = "s3://stpubdata/hst/public/j8pu/j8pu0y010/j8pu0y010_drc.fits"

使用 use_fsspec 启用后,您可以以与上述相同的方式从Amazon S3云存储中存储的文件中获取一个小剪贴。打开带有前缀的路径时 s3:// (Amazon S3存储)或 gs:// (谷歌云存储)、 open 将自动默认为 use_fsspec=True 为了方便起见。例如:

>>> # Download a small 10-by-20 pixel cutout from a FITS file stored in Amazon S3
>>> with fits.open(s3_uri, fsspec_kwargs={"anon": True}) as hdul:  
...     cutout = hdul[1].section[10:20, 30:50]

如果您的代码运行在与数据位于同一Amazon云区域的服务器上,则以这种方式从Amazon S3获取截图可能会特别有效。

备注

打开带有前缀的路径的步骤 s3:// ,fsspec需要一个可选的依赖项,称为 s3fs 。一个 ModuleNotFoundError 如果缺少此依赖项,则将引发。看见 安装 astropy 有关安装可选依赖项的详细信息,请参阅。

使用Amazon S3访问凭据#

在上面的示例中,我们传递了 fsspec_kwargs={"anon": True} 允许以匿名方式检索数据,而无需提供Amazon云访问凭据。这是可能的,因为数据位于已配置为允许匿名访问的公共S3存储桶中。

在某些情况下,您可能希望访问存储在Amazon S3数据桶中的数据,该数据桶是私有的或使用“请求者付费”功能。在这种情况下,您必须提供一个秘密访问密钥,以避免遇到 NoCredentialsError 。您可以使用 fsspec_kwargs 参数将额外的参数(如访问键)传递给 fsspec.open 功能如下:

>>> fsspec_kwargs = {"key": "YOUR-SECRET-KEY-ID",
...                  "secret": "YOUR-SECRET-KEY"}
>>> with fits.open(s3_uri, fsspec_kwargs=fsspec_kwargs) as hdul:
...     cutout = hdul[2].section[10:20, 30:50]

警告

在Python代码中包含秘密访问密钥是危险的,因为当您与他人共享代码时,您可能会意外地泄露您的密钥。更好的做法是通过配置文件或环境变量存储访问密钥。请参阅 s3fs 用于指导的文档。

vbl.使用 Cutout2D 使用云托管的FITS文件#

上面的示例使用 ImageHDU.section 该功能可在给定一组像素坐标的情况下下载小剪辑。对于天文图像,根据天空位置和角度大小获取截图通常比根据阵列坐标获取截图更方便。出于这个原因,Astropy提供了 astropy.nddata.Cutout2D 该工具使您可以轻松获取由图像的世界坐标系通知的裁剪 (WCS )。

此裁切工具可与 fsspec.section 。例如,假设您恰好知道我们在上面打开的图像在以下位置包含一个漂亮的边缘星系:

>>> # Approximate location of an edge-on galaxy
>>> from astropy.coordinates import SkyCoord
>>> position = SkyCoord('10h01m41.13s 02d25m20.58s')

我们还知道,银河系的半径约为5角秒:

>>> # Approximate size of the galaxy
>>> from astropy import units as u
>>> size = 5*u.arcsec

给定这个天空位置和半径,我们可以使用 Cutout2D 结合使用 use_fsspec=True.section 详情如下:

>>> from astropy.nddata import Cutout2D
>>> from astropy.wcs import WCS
...
>>> with fits.open(s3_uri, use_fsspec=True, fsspec_kwargs={"anon": True}) as hdul:  
...     wcs = WCS(hdul[1].header)
...     cutout = Cutout2D(hdul[1].section,  # use `.section` rather than `.data`!
...                       position=position,
...                       size=size,
...                       wcs=wcs)

看见 二维剪切图像 有关此功能的更多详细信息,请参阅。

为远程FITS文件设置子集的性能改进提示#

在上面的示例中,我们解释了使用 use_fsspec=True 功能与 lazy_load_hdus=True 参数和 ImageHDU.section 功能,以获得良好的性能。

还有两个显著影响性能的其他因素,即:(I)FITS文件的结构,以及(Ii)的缓存和块大小配置 fsspec 。本节的其余部分将简要说明这两个因素。

将FITS文件结构与数据切片模式匹配#

多维数据在FITS文件中的组织顺序对子集性能起着重要作用。

Astropy使用行优先顺序来索引FITS数据。这意味着最右边的轴是文件中变化最快的轴。换句话说,最右边维度的数据往往位于文件的连续区域,因此最容易提取。

例如,在2D图像的情况下,切片 .section[0, :] 可以通过从文件下载一个连续的字节区域来获得。相比之下,切片 .section[:, 0] 需要访问分布在整个图像阵列中的字节。对于更高的维度也是如此,例如,获取切片 .section[0, :, :] 从3D立方体中获取数据的速度往往比请求 .section[:, :, 0]

获取与FITS文件的内部布局匹配良好的数据切片通常会产生最佳性能。如果子集设置性能对您很重要,您可能必须考虑修改FITS文件,以确保维度的排序与您的数据切片模式完全匹配。

配置 fsspec 数据块大小和下载策略#

这个 fsspec Package支持不同的数据读取和缓存策略,旨在一方面在网络请求数量和传输的总数据量之间找到平衡。默认情况下,fsspec将尝试使用缓冲的 read ahead 策略,类似于操作系统将本地文件加载到内存时所采用的策略。

您可以通过传递自定义参数来调优fsspec缓冲策略的性能 block_sizecache_type 参数设置为 fsspec.open 。您可以通过 fsspec_kwargs 的论点 astropy.io.fits.open 。例如,我们可以将fsspec配置为使用最低限度的缓冲读取 block_size 大小为1 MB,如下:

>>> fsspec_kwargs = {"block_size": 1_000_000, "cache_type": "bytes"}
>>> with fits.open(url, use_fsspec=True, fsspec_kwargs=fsspec_kwargs) as hdul:  
...     cutout = hdul[1].section[10:20, 30:50]

理想的配置将取决于网络的延迟和吞吐量,以及您要获取的数据的确切形状和大小。

请参阅 fsspec 文档,了解有关其选项的更多信息。