N维数据集 (astropy.nddata#

介绍#

这个 nddata package provides classes to represent images and other gridded data, some essential functions for manipulating images, and the infrastructure for package developers who wish to include support for the image classes. This subpackage was developed based on APE 7

入门#

NDData#

主要目的 NDData 是扮演一个 容器 用于数据、元数据和其他相关信息(如掩码)。

NDData 对象可以通过传递n维来实例化 numpy 数组::

>>> import numpy as np
>>> from astropy.nddata import NDData
>>> array = np.zeros((12, 12, 12))  # a 3-dimensional array with all zeros
>>> ndd1 = NDData(array)

或者可以转换成 numpy.ndarray ::

>>> ndd2 = NDData([1, 2, 3, 4])
>>> ndd2
NDData([1, 2, 3, 4])

并且可以通过 data 属性:

>>> ndd2.data
array([1, 2, 3, 4])

它还支持其他属性,如 unitmask 对于数据,a wcs (世界坐标系)和 uncertainty 数据和其他 meta 属性:

>>> data = np.array([1,2,3,4])
>>> mask = data > 2
>>> unit = 'erg / s'
>>> from astropy.nddata import StdDevUncertainty
>>> uncertainty = StdDevUncertainty(np.sqrt(data)) # representing standard deviation
>>> meta = {'object': 'fictional data.'}
>>> ndd = NDData(data, mask=mask, unit=unit, uncertainty=uncertainty,
...              meta=meta)
>>> ndd
NDData([1, 2, —, —], unit='erg / s')

表示仅显示 data ;其他属性需要直接访问,例如, ndd.mask 进入面具。

NDDataRef#

在这个纯粹的容器上, NDDataRef 实施:

  • A readwrite 访问方法 astropy 的统一文件I/O接口。

  • 简单的算术,如加、减、除、乘。

  • 切片。

实例的创建方式相同:

>>> from astropy.nddata import NDDataRef
>>> ndd = NDDataRef(ndd)
>>> ndd
NDDataRef([1, 2, —, —], unit='erg / s')

但也支持算术 (NDData算法 )比如加法:

>>> import astropy.units as u
>>> ndd2 = ndd.add([4, -3.5, 3, 2.5] * u.erg / u.s)
>>> ndd2
NDDataRef([ 5. , -1.5,  ———,  ———], unit='erg / s')

因为这些操作具有广泛的选项,所以使用诸如 + .

切片或索引 (切片和索引NDData )可能(如果某些属性无法切片,则发出警告)::

>>> ndd2[2:]  # discard the first two elements  
NDDataRef([———, ———], unit='erg / s')
>>> ndd2[1]   # get the second element  
NDDataRef(-1.5, unit='erg / s')

处理像图像这样的二维数据#

尽管 nddata 包支持任何类型的网格数据,本文将重点介绍使用 nddata 对于二维图像。首先,我们将构建一个二维图像,其中包含一些源、一些高斯噪声和一条“宇宙线”,我们稍后将对其进行遮罩。

实例#

首先,用一些源、一些高斯噪声和“宇宙线”构建一个二维图像:

>>> import numpy as np
>>> from astropy.modeling.models import Gaussian2D
>>> rng = np.random.default_rng()
>>> y, x = np.mgrid[0:500, 0:600]
>>> data = (Gaussian2D(1, 150, 100, 20, 10, theta=0.5)(x, y) +
...         Gaussian2D(0.5, 400, 300, 8, 12, theta=1.2)(x,y) +
...         Gaussian2D(0.75, 250, 400, 5, 7, theta=0.23)(x,y) +
...         Gaussian2D(0.9, 525, 150, 3, 3)(x,y) +
...         Gaussian2D(0.6, 200, 225, 3, 3)(x,y))
>>> data += 0.01 * rng.standard_normal((500, 600))
>>> cosmic_ray_value = 0.997
>>> data[100, 300:310] = cosmic_ray_value

这张图片的左下角有一个很大的“星系”,“宇宙射线”是图像中下部的水平线:

>>> import matplotlib.pyplot as plt
>>> plt.imshow(data, origin='lower')

(png, svg, pdf)

../_images/index-12.png

“宇宙射线”可以在这个测试图像中被屏蔽掉,就像这样:

>>> mask = (data == cosmic_ray_value)

CCDData 图像类#

这个 CCDData 对象与此包中的其他对象一样,可以存储数据、掩码和元数据。这个 CCDData 对象要求指定单位:

>>> from astropy.nddata import CCDData
>>> ccd = CCDData(data, mask=mask,
...               meta={'object': 'fake galaxy', 'filter': 'R'},
...               unit='adu')

切片#

切片的工作方式与您预期的遮罩和(如果存在)WCS,适当地切片:

>>> ccd2 = ccd[:200, :]
>>> ccd2.data.shape
(200, 600)
>>> ccd2.mask.shape
(200, 600)
>>> # Show the mask in a region around the cosmic ray:
>>> ccd2.mask[99:102, 299:311]
array([[False, False, False, False, False, False, False, False, False,
        False, False, False],
       [False,  True,  True,  True,  True,  True,  True,  True,  True,
         True,  True, False],
       [False, False, False, False, False, False, False, False, False,
        False, False, False]]...)

对于许多应用,它可能更方便使用 Cutout2D, described in image_utilities .

图像算法,包括不确定性#

提供了图像间基本算术运算的方法,包括不确定性的传播。支持三种不确定性类型:方差 (VarianceUncertainty ),标准差 (StdDevUncertainty ),和逆方差 (InverseVariance

实例#

此示例创建了一个不确定性,即泊松误差,存储为方差:

>>> from astropy.nddata import VarianceUncertainty
>>> poisson_noise = np.ma.sqrt(np.ma.abs(ccd.data))
>>> ccd.uncertainty = VarianceUncertainty(poisson_noise ** 2)

为了方便起见,也可以用 numpy 数组。在这种情况下,假定不确定度为标准偏差:

>>> ccd.uncertainty = poisson_noise
INFO: array provided for uncertainty; assuming it is a StdDevUncertainty. [astropy.nddata.ccddata]

如果我们复制图像并将其添加到原始图像中,则不确定性将按预期发生变化:

>>> ccd2 = ccd.copy()
>>> added_ccds = ccd.add(ccd2, handle_meta='first_found')
>>> added_ccds.uncertainty.array[0, 0] / ccd.uncertainty.array[0, 0] / np.sqrt(2) 
0.99999999999999989

阅读与写作#

A CCDData 可以保存到FITS文件:

>>> ccd.write('test_file.fits')

也可以从FITS文件中读入:

>>> ccd2 = CCDData.read('test_file.fits')

请注意,该单元存储在 BUNIT 关键字,如果存在,则从标头中读取。

有关读写可用关键字参数的详细帮助,可以通过 help() 方法如下:

>>> CCDData.read.help('fits')  # Get help on the CCDData FITS reader
>>> CCDData.writer.help('fits')  # Get help on the CCDData FITS writer

图像实用程序#

切口#

虽然直接切片是提取子帧的一种方法, Cutout2D 提供更方便的数据剪切访问。

实例#

这个例子在图片的左下角拉出了一个大的“星系”,切口的中心在 position ::

>>> from astropy.nddata import Cutout2D
>>> position = (149.7, 100.1)
>>> size = (81, 101)     # pixels
>>> cutout = Cutout2D(ccd, position, size)
>>> plt.imshow(cutout.data, origin='lower') 

(png, svg, pdf)

../_images/index-21.png

这个剪贴画还可以在原始图像上绘制:

>>> plt.imshow(ccd, origin='lower')  
>>> cutout.plot_on_original(color='white') 

(png, svg, pdf)

../_images/index-31.png

cutout还提供了在原始或剪切中查找像素坐标的方法;回想一下 position 是原始图像中切口的中心:

>>> position
(149.7, 100.1)
>>> cutout.to_cutout_position(position)  
(49.7, 40.099999999999994)
>>> cutout.to_original_position((49.7, 40.099999999999994))  
 (149.7, 100.1)

有关更多详细信息,包括从世界坐标系构造剪切以及处理超出原始图像边界的剪切的选项,请参见 二维剪切图像 .

调整图像大小#

功能 block_reduceblock_replicate 调整图像大小。

例子#

这个例子将图像的大小缩小了4倍。注意,结果是 numpy.ndarray ;掩码、元数据等被丢弃:

>>> from astropy.nddata import block_reduce, block_replicate
>>> smaller = block_reduce(ccd, 4)  
>>> smaller
array(...)
>>> plt.imshow(smaller, origin='lower')  

(png, svg, pdf)

../_images/index-41.png

默认情况下,两者 block_reduceblock_replicate 保存流量。

其他图像类#

有两个限制较少的类, NDDataArrayNDDataRef ,可用于保存图像数据。它们主要是那些希望通过从 nddata 包裹。它们之间的主要区别是:

  • NDDataRef 可以切片,并具有用于基本算术运算的方法,但用户需要使用其中一个不确定类来定义不确定性。看到了吗 NDDataRef 更多细节。它的大多数属性必须在创建对象时设置,因为它们是不可变的。

  • NDDataArray 延伸 NDDataRef 通过添加使其行为类似于 numpy 数组,并为多个属性添加setter。它缺乏自动识别和读取FITS文件中数据的能力,也不尝试自动设置WCS属性。

  • CCDData 延伸 NDDataArray 通过设置默认的不确定性类,设置对FITS文件的直接读/写,并自动设置WCS属性。

更一般的网格数据类#

中有两个泛型类。 nddata 包主要面向那些需要超出目前讨论的类的自定义图像类的用户,或者正在处理不是图像的网格数据的用户。

  • NDData 是用于保存常规网格数据的容器类。它包含一些基本属性,但没有切片或算术。关于这个班的更多信息在 NDData .

  • NDDataBase 是一个抽象基类,新网格数据类的开发人员可以将其子类化,以声明新类遵循 NDData 接口。更多细节在 子类别化 .

其他示例#

下面使用 nddata 这个框架的目的是为了帮助用户编写自己的图像类,或者寻找一个超越什么的图像类 CCDData 做。

使用 nddata#

性能提示#

  • 使用不确定性类 VarianceUncertainty 会比其他两个不确定性类更有效, InverseVarianceStdDevUncertainty . 为了便于误差传播,后两者被转换成方差,然后从方差转换回原始的不确定类型。性能差异应该很小。

  • 如果可能,通过将值设置为 np.nan 并使用 numpy 自动排除的函数和方法 np.nan ,像 np.nanmediannp.nanstd . 这通常比使用 numpy.ma.MaskedArray .

参考/API#