nexus(系统发育)文件阅读器(.nex,.trees)
项目描述
python-nexus
为python提供通用的系统发育nexus格式(.nex,.trees)读取器和写入器。
描述
python-nexus提供了简单的nexus文件格式读取/写入工具,以及一小套nexus操作脚本。
请注意,此库与系统发育数据格式(例如 https://en.wikipedia.org/wiki/Nexus_file)兼容,而不是与物理数据格式(例如 https://manual.nexusformat.org/)兼容。
注意:由于与另一个python包的名称冲突,此包必须作为 pip install python-nexus
安装,但作为 import nexus
导入。
用法
命令行界面
python-nexus
安装了一个命令 nexus
用于命令行使用。您可以通过以下方式检查其帮助信息:
nexus -h
Python API
读取 Nexus
>>> from nexus import NexusReader
>>> n = NexusReader.from_file('tests/examples/example.nex')
您还可以从字符串中加载
>>> n = NexusReader.from_string('#NEXUS\n\nbegin foo; ... end;')
NexusReader 会使用特定的 handlers
加载它识别出的每个 Nexus blocks
。
>>> n.blocks
{'foo': <nexus.handlers.GenericHandler object at 0x7f55d94140f0>}
>>> n = NexusReader('tests/examples/example.nex')
>>> n.blocks
{'data': <NexusDataBlock: 2 characters from 4 taxa>}
将块映射到处理器的字典作为 `nexus.reader.HANDLERS` 提供
>>> from nexus.reader import HANDLERS
>>> HANDLERS
{
'trees': <class 'nexus.handlers.tree.TreeHandler'>,
'taxa': <class 'nexus.handlers.taxa.TaxaHandler'>,
'characters': <class 'nexus.handlers.data.CharacterHandler'>,
'data': <class 'nexus.handlers.data.DataHandler'>
}
不在该字典中的任何块将使用 nexus.handlers.GenericHandler
进行解析。
NexusReader
可以使用 NexusReader.write
将 Nexus 写入字符串,或使用 NexusReader.write_to_file
写入到另一个文件
>>> output = n.write()
>>> n.write_to_file("mynewnexus.nex")
注意:如果您想对生成 Nexus 文件有更精细的控制,请尝试下面的 NexusWriter
。
块处理器
有针对某些已知 Nexus 块的特定 "处理器",包括常见的 'data'、'trees' 和 'taxa' 块。任何未知块都将使用 GenericHandler 进行解析。
所有处理器都扩展了 GenericHandler
类,并具有以下方法。
-
__init__(self, name=None, data=None)
__init__
是由NexusReader
调用以适当地解析块的内容(在data
中)。 -
write(self)
写入是由NexusReader
调用以将块的内容写入字符串(即重新生成 Nexus 格式以将文件保存到磁盘)。
generic
块处理器
通用的块处理器只是将块的每一行存储在 .block
中
n.blockname.block
['line1', 'line2', ... ]
data
块处理器
这些是 Nexus 文件中遇到的主要块,并包含数据矩阵。
因此,给定以下包含数据块的 Nexus 文件
#NEXUS
Begin data;
Dimensions ntax=4 nchar=2;
Format datatype=standard symbols="01" gap=-;
Matrix
Harry 00
Simon 01
Betty 10
Louise 11
;
End;
begin trees;
tree A = ((Harry:0.1,Simon:0.2),Betty:0.2)Louise:0.1;;
tree B = ((Simon:0.1,Harry:0.2),Betty:0.2)Louise:0.1;;
end;
您可以执行以下操作
找出有多少个字符
>>> n.data.nchar
2
询问有多少个分类单元
>>> n.data.ntaxa
4
获取分类单元名称
>>> n.data.taxa
['Harry', 'Simon', 'Betty', 'Louise']
获取 format
信息
>>> n.data.format
{'datatype': 'standard', 'symbols': '01', 'gap': '-'}
实际的数据矩阵是一个字典,您可以通过 .matrix
访问它
>>> n.data.matrix
defaultdict(<class 'list'>, {'Harry': ['0', '0'], 'Simon': ['0', '1'], 'Betty': ['1', '0'], 'Louise': ['1', '1']})
或者,您可以通过分类单元访问数据矩阵
>>> n.data.matrix['Simon']
['0', '1']
或者甚至像这样遍历它
>>> for taxon, characters in n.data:
... print(taxon, characters)
...
Harry ['0', '0']
Simon ['0', '1']
Betty ['1', '0']
Louise ['1', '1']
您还可以遍历位点(而不是分类单元)
>>> for site, data in n.data.characters.items():
... print(site, data)
...
0 {'Harry': '0', 'Simon': '0', 'Betty': '1', 'Louise': '1'}
1 {'Harry': '0', 'Simon': '1', 'Betty': '0', 'Louise': '1'}
..或者您可以直接访问字符矩阵
>>> n.data.characters[0]
{'Harry': '0', 'Simon': '0', 'Betty': '1', 'Louise': '1'}
注意:位点是从零开始的索引!
trees
块处理器
如果有 trees
块,则您可以执行以下操作
您可以获取树的数量
>>> n.trees.ntrees
2
您可以通过 .trees
字典访问树
>>> n.trees.trees[0]
'tree A = ((Harry:0.1,Simon:0.2):0.1,Betty:0.2):Louise:0.1);'
或者遍历它们
>>> for tree in n.trees:
... print(tree)
...
tree A = ((Harry:0.1,Simon:0.2):0.1,Betty:0.2):Louise:0.1);
tree B = ((Simon:0.1,Harry:0.2):0.1,Betty:0.2):Louise:0.1);
为了进一步通过 newick 包 检查树,您可以检索树的 nexus.Node
对象
>>> print(n.trees.trees[0].newick_tree.ascii_art())
┌─Harry
┌────────┤
──Louise─┤ └─Simon
└─Betty
taxa
块处理器
像 SplitsTree 这样的程序可以理解 Nexus 文件中的 "TAXA" 块
BEGIN Taxa;
DIMENSIONS ntax=4;
TAXLABELS
[1] 'John'
[2] 'Paul'
[3] 'George'
[4] 'Ringo'
;
END; [Taxa]
在分类单元块中,您可以获取分类单元数量和分类单元列表
>>> n.taxa.ntaxa
4
>>> n.taxa.taxa
['John', 'Paul', 'George', 'Ringo']
注意:使用这种替代 Nexus 格式时,字符块应该由 DataHandler 解析。
使用 NexusWriter 编写 Nexus 文件
NexusWriter
提供了更精细的控制来编写 Nexus 文件,如果您是程序性地生成 Nexus 文件而不是加载现有的 Nexus 文件,那么它很有用。
>>> from nexus import NexusWriter
>>> n = NexusWriter()
>>> #Add a comment to appear in the header of the file
>>> n.add_comment("I am a comment")
使用 "add" 函数添加数据,该函数接受 3 个参数:一个分类单元、一个字符名称和一个值。
>>> n.add('taxon1', 'Character1', 'A')
>>> n.data
{'Character1': {'taxon1': 'A'}}
>>> n.add('taxon2', 'Character1', 'C')
>>> n.add('taxon3', 'Character1', 'A')
字符和值可以是字符串或整数(但不能混合字符串和整数字符)。
>>> n.add('taxon1', 2, 1)
>>> n.add('taxon2', 2, 2)
>>> n.add('taxon3', 2, 3)
NexusWriter 将插入缺失的条目(即在此例中为 taxon2)
>>> n.add('taxon1', "Char3", '4')
>>> n.add('taxon3', "Char3", '4')
... 当您准备就绪时,您可以使用 make_nexus
或 write_to_file
生成 Nexus
>>> data = n.make_nexus(interleave=True, charblock=True, preserve_order=False)
>>> n.write_to_file("output.nex", interleave=True, charblock=True, preserve_order=False)
... 您可以通过将 interleave
设置为 True 来创建交错 Nexus,并且您可以通过将 charblock 设置为 True 在 Nexus 中包含字符块(例如,如果您有字符标签)此外,您可以指定是否应该保留添加的分类单元和字符的顺序,通过将 preserve_order
设置为 True,否则它们将被按字母数字顺序排序。
处理树的基本支持
>>> n.trees.append("tree tree1 = (a,b,c);")
>>> n.trees.append("tree tree2 = (a,b,c);")
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。