用于处理位掩码和掩码数组的实用函数#

这是很常见的 bit fields ,例如整数变量,其单个位表示某些属性,以表征数据的状态。例如,哈勃太空望远镜(HST)使用位场阵列来描述HST图像的数据质量(DQ)。例如,请参见的DQ字段值 WFPC2 image data (see Table 3.3)WFC3 image data (see Table 3.3) . 如你所见 位标志 因为这两种工具一般是不同的。

位字段可以看作是位标志的紧密压缩集合。使用 masking 我们可以“检查”单个位的状态。

对位字段数组执行的一个常见操作是将它们转换为布尔掩码,例如,通过分配布尔值 True (在布尔掩码中)对应于非零值位字段(至少有一位设置为的位字段)的那些元素 1 )或者,通常通过分配 True 对应的位字段只有 特定字段 设置(到 1 ). 这种更复杂的位域分析可以使用 位掩码 以及前面提到的掩蔽操作。

这个 bitmask 模块提供两个功能,方便将位字段数组(即DQ数组)转换为布尔掩码: bitfield_to_boolean_mask 使用输入位掩码(或单个位标志列表)和将输入位字段数组转换为布尔掩码 interpret_bit_flags 从单个位标志的输入列表创建位掩码。

创建布尔掩码#

概述#

bitfield_to_boolean_mask 默认情况下,假设至少有一个位打开的所有输入位字段对应于“坏”数据(即像素),并将其转换为布尔值 True 在输出布尔掩码中(否则输出布尔掩码值设置为 False

通常,对于特定的算法和情况,一些位标志是可以忽略的。 bitfield_to_boolean_mask 接受位标志的列表 默认情况下必须忽略 创建布尔掩码时在输入位字段中。

从根本上说, 默认情况下bitfield_to_boolean_mask 执行以下操作:

(1)    boolean_mask = (bitfield & ~bit_mask) != 0

(这里 & 是按位的 and 虽然 ~ 是按位的 not 在前面的公式中, bit_mask 是从需要在位字段中忽略的各个位标志创建的位掩码。

例子#

表1:布尔掩码计算示例(默认参数和8位数据类型)#

位场

位掩码

~(位掩码)

位域&~(位掩码)

布尔掩码

11011001(217)

01010000(80)

10101111(175)

10001001(137)

11011001(217)

10101111(175)

01010000(80)

01010000(80)

00001001(9)

01001001(73)

10110110(182)

00000000(0)

00001001(9)

00000000(0)

(111255页)

00001001(9)

00001001(9)

(111255页)

00000000(0)

00000000(0)

指定位标志#

bitfield_to_boolean_mask 接受整数位掩码或位标志列表。位标志的列表将组合成一个位掩码,并且可以作为 整型位标志值 或以逗号分隔(或 + -分隔)整型位标志值的列表。请考虑中第一个示例中的位掩码 Table 1 . 在这种情况下 ignore_flags 可以设置为:

  • 整数值位掩码80

  • 表示单个非零的Python列表 位标志值: [16, 64]

  • 以逗号分隔的字符串 位标志值或助记符名称'16,64''CR,WARM'

  • 一串 + -分开的 位标志值或助记符名称'16+64''CR+WARM'

例子#

指定位标志:

>>> from astropy.nddata import bitmask
>>> import numpy as np
>>> bitmask.bitfield_to_boolean_mask(217, ignore_flags=80)
array(True...)
>>> bitmask.bitfield_to_boolean_mask(217, ignore_flags='16,64')
array(True...)
>>> bitmask.bitfield_to_boolean_mask(217, ignore_flags=[16, 64])
array(True...)
>>> bitmask.bitfield_to_boolean_mask(9, ignore_flags=[1, 8, 64])
array(False...)
>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags='1,8,64')
array([False,  True, False,  True]...)

也可以指定输出掩码的类型:

>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags='1,8,64', dtype=np.uint8)
array([0, 1, 0, 1], dtype=uint8)

为了使用助记符位标志名的列表,必须提供一个map,它是 BitFlagNameMap ,可用于将助记符名称映射到位标志值。这些地图通常由第三方提供。映射中的每个位标志也可以在标志值后面包含一个字符串注释。在下面的示例中,我们定义了一个简单的遮罩贴图:

>>> from astropy.nddata.bitmask import BitFlagNameMap
>>> class ST_DQ(BitFlagNameMap):
...     CR = 1
...     CLOUDY = 4
...     RAINY = 8, 'Dome closed'
...     HOT = 32
...     DEAD = 64
>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags='CR,RAINY,DEAD',
...                                  dtype=np.uint8, flag_name_map=ST_DQ)
array([0, 1, 0, 1], dtype=uint8)

使用位标志名称映射#

为了允许使用助记位标志名来描述在创建 布尔 掩码,我们使用位标志名映射。这些映射将助记符位标志名转换为相应的整数值,不区分大小写。

位标志名称映射是 BitFlagNameMap 可以用两种方式构造,或者直接通过子类化 BitFlagNameMap ,例如,

>>> from astropy.nddata.bitmask import BitFlagNameMap
>>> class ST_DQ(BitFlagNameMap):
...     CR = 1
...     CLOUDY = 4
...     RAINY = 8
...
>>> class ST_CAM1_DQ(ST_DQ):
...     HOT = 16
...     DEAD = 32

或通过使用 extend_bit_flag_map 等级工厂:

>>> from astropy.nddata.bitmask import extend_bit_flag_map
>>> ST_DQ = extend_bit_flag_map('ST_DQ', CR=1, CLOUDY=4, RAINY=8)
>>> ST_CAM1_DQ = extend_bit_flag_map('ST_CAM1_DQ', ST_DQ, HOT=16, DEAD=32)

备注

位标志值必须是2的幂的整数。

一旦构造完成,就不能修改、删除或添加映射的位标志值。只有通过使用上面所示的两种方法之一的子类化或通过添加形式的元组列表,才允许向映射添加标志 ('NAME', value) 全班同学。这将从原始映射创建一个新的map类,但包含其他标志

>>> ST_CAM1_DQ = ST_DQ + [('HOT', 16), ('DEAD', 32)]

会产生与上面所示的子类化或类工厂示例中相同的映射。

创建位标志名称映射后,位标志值可以作为 case-insensitive 字典中的类属性或键:

>>> ST_CAM1_DQ.cloudy
4
>>> ST_CAM1_DQ['Rainy']
8

修改用于创建布尔掩码的公式#

bitfield_to_boolean_mask 提供几个参数,可用于修改用于创建布尔掩码的公式。

反转位掩码#

有时更方便的是能够指定那些位标志 必须考虑 创建布尔掩码时,所有其他标志都应忽略。

例子#

bitfield_to_boolean_mask specifying bit flags that must be considered when creating the boolean mask can be accomplished by setting the parameter flip_bits to True. This effectively modifies equation (1) 到:

(2)    boolean_mask = (bitfield & bit_mask) != 0

所以,不是:

>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags=[1, 8, 64])
array([False,  True, False,  True]...)

您可以获得相同的结果:

>>> bitmask.bitfield_to_boolean_mask(
...     [9, 10, 73, 217], ignore_flags=[2, 4, 16, 32, 128], flip_bits=True
... )
array([False,  True, False,  True]...)

但请注意,何时 ignore_flags 是位标志值的逗号分隔列表, flip_bits 不能设置为 TrueFalse . 相反,要翻转由逗号分隔的位标志值的字符串列表形成的位掩码的位,可以在 ~ 列表中:

>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags='~2+4+16+32+128')
array([False,  True, False,  True]...)

反转布尔掩码#

其他时候,可能更方便地获得反向掩码,其中标记的数据被转换为 False 而不是 True

(3)    boolean_mask = (bitfield & ~bit_mask) == 0

这可以通过改变 good_mask_value 参数的默认值 (FalseTrue .

例子#

转换为获取被标记的数据的掩码 False 而不是 True

>>> bitmask.bitfield_to_boolean_mask([9, 10, 73, 217], ignore_flags=[1, 8, 64],
...                                  good_mask_value=True)
array([ True, False,  True, False]...)