可变XML处理 (astropy.io.votable#

介绍#

这个 astropy.io.votable 子程序包在可投票的XML文件之间进行相互转换 numpy 记录数组。此子程序包最初开发为 vo.table

入门#

本节简要介绍如何使用 astropy.io.votable 。我们的目标是在不涉及太多细节的情况下演示该包的基本功能。

备注

如果要以可投票格式读取或写入单个表,推荐的方法是通过高级 统一文件读写接口 。特别是请参阅 Unified I/O VOTables 一节。

读取VOTable文件#

要读入VOTable文件,请将文件路径传递给 parse ::

from astropy.io.votable import parse
votable = parse("votable.xml")

votable 是一个 VOTableFile 对象,可用于检索和操作数据并将其保存回磁盘。

VOTable文件由嵌套的 RESOURCE 元素,每个元素可以包含一个或多个 TABLE 元素。这个 TABLE 元素包含数据数组。

到达 TABLE 元素,可以在 VOTABLE 文件::

for resource in votable.resources:
    for table in resource.tables:
        # ... do something with the table ...
        pass

但是,如果资源的嵌套结构不重要,则可以使用 iter_tables 要返回所有表的简单列表:

for table in votable.iter_tables():
    # ... do something with the table ...
    pass

最后,如果希望文件中只有一个表,那么使用它可能最方便 get_first_table ::

table = votable.get_first_table()

或者,有一种方便的方法来解析VOTable文件并在一个步骤中返回第一个表:

from astropy.io.votable import parse_single_table
table = parse_single_table("votable.xml")

从一个 TableElement 对象,则可以在 array 成员变量::

data = table.array

此数据是 numpy 记录数组。

列的名称来自 IDname 的属性 FIELD 中的元素 VOTABLE 文件。

实例#

假设我们有 FIELD 具体如下:

<FIELD ID="Dec" name="dec_targ" datatype="char" ucd="POS_EQ_DEC_MAIN"
       unit="deg">
 <DESCRIPTION>
  representing the ICRS declination of the center of the image.
 </DESCRIPTION>
</FIELD>

备注

VOTable映射 nameID 属性到 numpy D型 namestitles 非常令人困惑。

在VOTable中, ID 保证是唯一的,但不是必需的。 name 不保证是唯一的,但是必需的。

numpy 记录数据类型, names 必须是唯一的,并且是必需的。 titles 不是必需的,也不要求是唯一的。

因此,VOTable的 ID 最接近于 numpynames ,和VOTable的 name 最接近于 numpytitles . 但是,在某些情况下 ID 未提供,a numpy name 将基于VOTable生成 name . 不幸的是,VOTable字段没有既唯一又必需的属性,这是唯一标识列的最方便的机制。

在从 astropy.io.votable.tree.TableElement 对象添加到一个 astropy.table.Table 对象,则可以指定是否优先考虑 nameID 属性来命名列。默认情况下, ID 会被优先考虑。给予 name 首选项,则传递关键字参数 use_names_over_ids=True **

>>> votable.get_first_table().to_table(use_names_over_ids=True)

可以使用以下方法从记录数组中提取此数据列:

>>> table.array['dec_targ']
array([17.15153360566, 17.15153360566, 17.15153360566, 17.1516686826,
       17.1516686826, 17.1516686826, 17.1536197136, 17.1536197136,
       17.1536197136, 17.15375479055, 17.15375479055, 17.15375479055,
       17.1553884541, 17.15539736932, 17.15539752176,
       17.25736014763,
       # ...
       17.2765703], dtype=object)

或相当于:

>>> table.array['Dec']
array([17.15153360566, 17.15153360566, 17.15153360566, 17.1516686826,
       17.1516686826, 17.1516686826, 17.1536197136, 17.1536197136,
       17.1536197136, 17.15375479055, 17.15375479055, 17.15375479055,
       17.1553884541, 17.15539736932, 17.15539752176,
       17.25736014763,
       # ...
       17.2765703], dtype=object)

从头开始构建新表#

还可以构建一个新表,定义一些字段数据类型,并用数据填充它。

例子#

要从VOTable文件生成新表,请执行以下操作:

from astropy.io.votable.tree import VOTableFile, Resource, TableElement, Field

# Create a new VOTable file...
votable = VOTableFile()

# ...with one resource...
resource = Resource()
votable.resources.append(resource)

# ... with one table
table = TableElement(votable)
resource.tables.append(table)

# Define some fields
table.fields.extend([
        Field(votable, name="filename", datatype="char", arraysize="*"),
        Field(votable, name="matrix", datatype="double", arraysize="2x2")])

# Now, use those field definitions to create the numpy record arrays, with
# the given number of rows
table.create_arrays(2)

# Now table.array can be filled with data
table.array[0] = ('test1.xml', [[1, 0], [0, 1]])
table.array[1] = ('test2.xml', [[0.5, 0.3], [0.2, 0.1]])

# Now write the whole thing to a file.
# Note, we have to use the top-level votable file object
votable.to_xml("new_votable.xml")

输出VOTable文件#

方法以可投票格式写入表格数据。 votable 直接打包。然而,在某些情况下,高层 统一文件读写接口 通常就足够了,而且使用起来也更方便一些。请参阅 Unified I/O VOTable 部分了解详细信息。

要保存VOTable文件,请调用 to_xml 方法。它接受字符串或Unicode路径,或类似于Python文件的对象:

votable.to_xml('output.xml')

支持多种数据存储格式 astropy.io.votable 。这个 TABLEDATA 格式是基于XML的,并将值存储为表示数字的字符串。这个 BINARY 格式更加紧凑,以Base64编码的二进制格式存储数字。Vvotable版本1.3增加了 BINARY2 格式,该格式允许屏蔽任何数据类型,包括无法在旧版本中屏蔽的整数和位域 BINARY 格式化。在每个表的基础上使用 format 属性,或全局使用 set_all_tables_format 方法:

votable.get_first_table().format = 'binary'
votable.set_all_tables_format('binary')
votable.to_xml('binary.xml')

使用 astropy.io.votable#

标准符合性#

astropy.io.votable.tree.TableElement 支持 VOTable Format Definition Version 1.1Version 1.2Version 1.3 ,以及 Version 1.4 。提供了一些灵活性来支持1.0草案版本和其他非标准用法,请参见 验证VOTables 了解更多详细信息。

备注

发出的每个警告和特定于VOTABLE的异常都有一个数字,在中有更详细的记录 警告例外情况 .

输出始终符合1.1、1.2、1.3或1.4规范,具体取决于输入。

验证VOTables#

野外的许多可投票文件不符合可投票规范。方法设置遇到冲突时应发生的情况。 verify 关键字,可以接受三个值:

这个 verify 关键字可以与 parse()parse_single_table() 功能::

from astropy.io.votable import parse
votable = parse("votable.xml", verify='warn')

可以更改默认设置 verify 通过以下方式实现价值 astropy.io.votable.conf.verify 项目中的 配置系统 (astropy.config )

请注意 'ignore''warn' 我的意思是 astropy 将尝试解析投票表,但如果违反了规范,则不能保证成功。

最好将任何错误报告给生成可投票文件的应用程序的作者,以使该文件符合规范。

缺少值#

表中的任何值都可能“丢失”。 astropy.io.votable 存储为 numpy 每个中的掩码数组 TableElement 举个例子。这就像一个普通的 numpy 掩码数组,可变长度字段除外。对于这些字段,列的数据类型为“Object”和另一个 numpy 掩码数组存储在那里。因此,对可变长度列的操作不起作用-这是因为不直接支持可变长度列 numpy 掩码数组。

数据类型映射#

由指定的数据类型 FIELD 元素映射到 numpy 根据下表键入:

VOTABLE类型

NumPy类型

布尔

地下一层

一点

地下一层

无符号字节

u1

字符( 可变长度

O-A型 bytes() 对象。

字符( 固定长度

S

独角兽( 可变长度

O-A型 str 对象

独角兽( 固定长度

U

短的

I2

利息

i4号

长的

十八

浮动

4层

双重的

8楼

漂浮物

第八章

双重复合体

c16型

如果字段是固定大小的数组,则数据存储为 numpy 固定大小数组。

如果数组的大小是一个变量, arraysize 包含“*”),则单元格将包含 numpy 价值观。每个值可以是数组或标量,具体取决于 arraysize 说明符。

检查字段类型#

若要查找有关表中某个字段的更多信息,可以使用 get_field_by_id 方法,该方法返回 Field 具有给定ID的。

例子#

要查找有关字段的更多信息,请执行以下操作:

>>> field = table.get_field_by_id('Dec')
>>> field.datatype
'char'
>>> field.unit
'deg'

备注

不应更改字段描述符。若要更改列集,请将表转换为 astropy.table.Table ,进行更改,然后将其转换回原处。

数据序列化格式#

VOTable支持多种不同的序列化格式。

  • TABLEDATA 将数据存储在纯XML中,其中的数值作为人类可读的字符串写入。

  • BINARY 是数据的二进制表示,以不透明的形式存储在XML中 base64 -编码的blob。

  • BINARY2 是在VOTable 1.3中添加的,与“BINARY”相同,只是它显式地记录了缺失值的位置,而不是用一个特殊的值来标识它们。

  • FITS 将数据存储在外部FITS文件中。不支持此序列化 astropy.io.votable writer,因为它需要写入多个文件。

  • PARQUET 将数据存储在外部拼图文件中,类似于FITS序列化。读取和写入完全受 astropy.io.votable 作家和 astropy.io.votable.parse 读者。可以使用绝对路径和相对路径引用拼图文件。拼图序列化可以用作统一表I/O的一部分(请参阅下一节),方法是设置 format 参数为 'votable.parquet'

可通过两种方式选择序列化格式:

1)通过设置 format 对象的属性 astropy.io.votable.tree.TableElement 对象::

votable.get_first_table().format = "binary"
votable.to_xml("new_votable.xml")

2) 通过使用 tabledata_format 写出VOTable文件时的关键字参数::

votable.to_xml("new_votable.xml", tabledata_format="binary")

转换为/从 astropy.table.Table#

VOTable标准在概念上并不映射到 astropy.table.Table . 但是,在 VOTable 文件可以转换为 astropy.table.Table ::

from astropy.io.votable import parse_single_table
table = parse_single_table("votable.xml").to_table()

为了方便起见,还有一个函数可以创建一个完整的VOTable文件,其中只有一个表:

from astropy.io.votable import from_table, writeto
votable = from_table(table)
writeto(votable, "output.xml")

备注

默认情况下, to_table 将使用 ID 属性来创建 Table 对象。但是,您可能希望使用 name 而是属性。为此,设置 use_names_over_ids 关键字到 True . 请注意,因为字段 names 不保证在VOTable规范中是唯一的,但列名在中必须是唯一的 numpy 结构化数组(因此 astropy.table.Table 对象),在某些情况下,可以通过在末尾附加数字来重命名名称。

性能注意事项#

如果 TABLE 元素包括 nrows 属性。如果未指定行数,则必须在加载期间重复调整记录数组的大小。

读写VO模型注释#

介绍#

VOTables中的模型实例 (MIVOT )定义了将可投票数据映射到以VO-DML(虚拟观察站数据建模语言)序列化的任何模型的语法。该注释模式充当数据和模型之间的桥梁。它将列/参数元数据和投票表中的数据与数据模型元素(类、属性、类型等)相关联。它还调出表中可能缺失的可投票数据或元数据,例如坐标系描述或管理跟踪。数据模型元素被分组到符合MIVOT XML模式的独立注释块中,该注释块作为额外资源添加到表元素之上。MIVOT语法允许将数据结构描述为类的层次结构。它还能够表示它们之间的关系和组成。此外,它还可以通过聚合来自投票表的不同表的实例来构建数据模型对象。

Astroy实现#

Astropy的目的不是处理VO注释。它只是允许相关的包从VOTables获取MIVOT块并将其设置到VOTables。因此,在此实现中,MIVOT注释既作为字符串导入,也作为字符串导出。当前实现防止客户端代码注入非MIVOT序列化的VOTables字符串。

MivotBlock实施:

  • MIVOT块由 astropy.io.votable.tree.MivotBlock 班级。

  • MivotBlock实例只能由带有“type=meta”的资源承载。

  • 此实例将XML映射块作为字符串保存。

  • MivotBlock对象由资源解析器实例化。

  • MivotBlock类有自己的逻辑,可以同时操作解析和IO功能。

例子#

   <VOTABLE xmlns="http://www.ivoa.net/xml/VOTable/v1.3"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3">
     <RESOURCE>
       <RESOURCE type="meta">
         <VODML xmlns="http://www.ivoa.net/xml/mivot">
          ...
         </VODML>
       </RESOURCE>
       <TABLE name="myDataTable">
        ....
       </TABLE>
     </RESOURCE>
</VOTABLE>

读取包含MIVOT块的表格表#

要读入包含或不包含MIVOT资源的VOTABLE文件,请将文件路径传递到`~ASTOSTPY.io.voable.parse`:

>>> from astropy.io.votable import parse
>>> from astropy.utils.data import get_pkg_data_filename
>>> votable = parse(get_pkg_data_filename("data/test.order.xml", package="astropy.io.votable.tests"))
<VODML xmlns="http://www.ivoa.net/xml/mivot">
</VODML>

<VODML xmlns="http://www.ivoa.net/xml/mivot">
</VODML>

如果Parse函数检测到MIVOT块,它将调用MIVOT解析器。

构建包含MIVOT块的资源#

通过将XML块作为参数传递来构造MIVOT块:

>>> from astropy.io.votable import tree
>>> from astropy.io.votable.tree import MivotBlock, Resource, VOTableFile
>>> mivot_block = MivotBlock("""
<VODML xmlns="http://www.ivoa.net/xml/mivot" >
   <REPORT status="OK">Unit test mapping block</REPORT>
   <GLOBALS>  </GLOBALS>
</VODML>
""")

构建新资源:

>>> mivot_resource = Resource()

将其类型指定为META:

>>> mivot_resource.type = "meta"

然后将其添加到MIVOT块:

>>> mivot_resource.mivot_block = mivot_block

现在,您有了一个MIVOT资源,您可以将其添加到创建新资源的对象资源中:

>>> votable = VOTableFile()
>>> r1 = Resource()
>>> r1.type = "results"
>>> r1.resources.append(mivot_resource)

您可以添加一个 astropy.io.votable.tree.TableElement 至资源:

>>> table = tree.TableElement(votable)
>>> r1.tables.append(t1)
>>> votable.resources.append(r1)
>>> for resource in votable.resources:
...     print(resource.mivot_block.content)
<VODML xmlns="http://www.ivoa.net/xml/mivot" >
   <REPORT status="OK">Unit test mapping block</REPORT>
   <GLOBALS>  </GLOBALS>
</VODML>

也见#

参考/API#