Swiss-Prot 和 ExPASy

解析 Swiss-Prot 文件

Swiss-Prot (https://web.expasy.org/docs/swiss-prot_guideline.html) 是一个手工整理的蛋白质序列数据库。Biopython 可以解析“纯文本”Swiss-Prot 文件格式,这种格式仍然用于 UniProt 知识库,该知识库合并了 Swiss-Prot、TrEMBL 和 PIR-PSD。

虽然我们在下面重点介绍旧的人类可读纯文本格式,但 Bio.SeqIO 可以读取这种格式和较新的 UniProt XML 文件格式,用于注释蛋白质序列。

解析 Swiss-Prot 记录

在第 从网络解析 SwissProt 序列 节中,我们描述了如何将 Swiss-Prot 记录的序列提取为 SeqRecord 对象。或者,你可以将 Swiss-Prot 记录存储在 Bio.SwissProt.Record 对象中,实际上该对象存储了 Swiss-Prot 记录中包含的完整信息。在本节中,我们描述了如何从 Swiss-Prot 文件中提取 Bio.SwissProt.Record 对象。

要解析 Swiss-Prot 记录,我们首先获取 Swiss-Prot 记录的句柄。根据 Swiss-Prot 记录的存储位置和方式,有几种方法可以做到这一点

  • 在本地打开 Swiss-Prot 文件

    >>> handle = open("SwissProt/F2CXE6.txt")
    
  • 打开一个压缩的 Swiss-Prot 文件

    >>> import gzip
    >>> handle = gzip.open("myswissprotfile.dat.gz", "rt")
    
  • 通过互联网打开 Swiss-Prot 文件

    >>> from urllib.request import urlopen
    >>> url = "https://raw.githubusercontent.com/biopython/biopython/master/Tests/SwissProt/F2CXE6.txt"
    >>> handle = urlopen(url)
    

    在调用 read 之前打开存储在互联网上的文件。

  • 通过 ExPASy 数据库(见第 检索 Swiss-Prot 记录 节)通过互联网打开 Swiss-Prot 文件

    >>> from Bio import ExPASy
    >>> handle = ExPASy.get_sprot_raw("F2CXE6")
    

关键在于,对于解析器来说,句柄是如何创建的并不重要,只要它指向 Swiss-Prot 格式的数据即可。如果句柄以二进制模式打开,解析器会自动将数据解码为 ASCII(Swiss-Prot 使用的编码)。

我们可以使用 Bio.SeqIO,如第 从网络解析 SwissProt 序列 节所述,获取与文件格式无关的 SeqRecord 对象。或者,我们可以使用 Bio.SwissProt 获取 Bio.SwissProt.Record 对象,这些对象更接近底层文件格式。

要从句柄中读取一个 Swiss-Prot 记录,我们使用函数 read()

>>> from Bio import SwissProt
>>> record = SwissProt.read(handle)

如果句柄正好指向一个 Swiss-Prot 记录,应该使用此函数。如果找不到 Swiss-Prot 记录,或者找到多个记录,它都会引发 ValueError

现在我们可以打印一些关于此记录的信息

>>> print(record.description)
SubName: Full=Plasma membrane intrinsic protein {ECO:0000313|EMBL:BAN04711.1}; SubName: Full=Predicted protein {ECO:0000313|EMBL:BAJ87517.1};
>>> for ref in record.references:
...     print("authors:", ref.authors)
...     print("title:", ref.title)
...
authors: Matsumoto T., Tanaka T., Sakai H., Amano N., Kanamori H., Kurita K., Kikuta A., Kamiya K., Yamamoto M., Ikawa H., Fujii N., Hori K., Itoh T., Sato K.
title: Comprehensive sequence analysis of 24,783 barley full-length cDNAs derived from 12 clone libraries.
authors: Shibasaka M., Sasano S., Utsugi S., Katsuhara M.
title: Functional characterization of a novel plasma membrane intrinsic protein2 in barley.
authors: Shibasaka M., Katsuhara M., Sasano S.
title:
>>> print(record.organism_classification)
['Eukaryota', 'Viridiplantae', 'Streptophyta', 'Embryophyta', 'Tracheophyta', 'Spermatophyta', 'Magnoliophyta', 'Liliopsida', 'Poales', 'Poaceae', 'BEP clade', 'Pooideae', 'Triticeae', 'Hordeum']

要解析包含多个 Swiss-Prot 记录的文件,我们使用 parse 函数。此函数允许我们迭代文件中的记录。

例如,让我们解析完整的 Swiss-Prot 数据库并收集所有描述。你可以从 ExPASy FTP 站点 下载这个数据库,它是一个名为 uniprot_sprot.dat.gz(大约 300MB)的压缩文件。这是一个包含单个文件 uniprot_sprot.dat(超过 1.5GB)的压缩文件。

如本节开头所述,你可以使用 Python 库 gzip 打开和解压缩 .gz 文件,例如

>>> import gzip
>>> handle = gzip.open("uniprot_sprot.dat.gz", "rt")

但是,解压缩大型文件需要时间,并且每次以这种方式打开文件进行读取时,都需要动态解压缩。因此,如果你有足够的磁盘空间,将文件解压缩到磁盘后,你将节省大量时间,从而获得内部的 uniprot_sprot.dat 文件。然后,你可以像往常一样打开文件进行读取

>>> handle = open("uniprot_sprot.dat")

截至 2009 年 6 月,从 ExPASy 下载的完整 Swiss-Prot 数据库包含 468851 个 Swiss-Prot 记录。构建记录描述列表的一种简洁方法是使用列表推导

>>> from Bio import SwissProt
>>> handle = open("uniprot_sprot.dat")
>>> descriptions = [record.description for record in SwissProt.parse(handle)]
>>> len(descriptions)
468851
>>> descriptions[:5]
['RecName: Full=Protein MGF 100-1R;',
 'RecName: Full=Protein MGF 100-1R;',
 'RecName: Full=Protein MGF 100-1R;',
 'RecName: Full=Protein MGF 100-1R;',
 'RecName: Full=Protein MGF 100-2L;']

或者,使用 for 循环遍历记录迭代器

>>> from Bio import SwissProt
>>> descriptions = []
>>> handle = open("uniprot_sprot.dat")
>>> for record in SwissProt.parse(handle):
...     descriptions.append(record.description)
...
>>> len(descriptions)
468851

由于这是一个非常大的输入文件,无论哪种方式,在我的新台式电脑上(使用未压缩的 uniprot_sprot.dat 文件作为输入)都需要大约 11 分钟。

从 Swiss-Prot 记录中提取任何你想要的信息同样容易。要查看 Swiss-Prot 记录的成员,请使用

>>> dir(record)
['__doc__', '__init__', '__module__', 'accessions', 'annotation_update',
'comments', 'created', 'cross_references', 'data_class', 'description',
'entry_name', 'features', 'gene_name', 'host_organism', 'keywords',
'molecule_type', 'organelle', 'organism', 'organism_classification',
'references', 'seqinfo', 'sequence', 'sequence_length',
'sequence_update', 'taxonomy_id']

解析 Swiss-Prot 关键词和类别列表

Swiss-Prot 还发布了一个名为 keywlist.txt 的文件,其中列出了 Swiss-Prot 中使用的关键词和类别。该文件以以下形式包含条目

ID   2Fe-2S.
AC   KW-0001
DE   Protein which contains at least one 2Fe-2S iron-sulfur cluster: 2 iron
DE   atoms complexed to 2 inorganic sulfides and 4 sulfur atoms of
DE   cysteines from the protein.
SY   Fe2S2; [2Fe-2S] cluster; [Fe2S2] cluster; Fe2/S2 (inorganic) cluster;
SY   Di-mu-sulfido-diiron; 2 iron, 2 sulfur cluster binding.
GO   GO:0051537; 2 iron, 2 sulfur cluster binding
HI   Ligand: Iron; Iron-sulfur; 2Fe-2S.
HI   Ligand: Metal-binding; 2Fe-2S.
CA   Ligand.
//
ID   3D-structure.
AC   KW-0002
DE   Protein, or part of a protein, whose three-dimensional structure has
DE   been resolved experimentally (for example by X-ray crystallography or
DE   NMR spectroscopy) and whose coordinates are available in the PDB
DE   database. Can also be used for theoretical models.
HI   Technical term: 3D-structure.
CA   Technical term.
//
ID   3Fe-4S.
...

该文件中的条目可以通过 Bio.SwissProt.KeyWList 模块中的 parse 函数进行解析。然后,每个条目都被存储为 Bio.SwissProt.KeyWList.Record,它是一个 Python 字典。

>>> from Bio.SwissProt import KeyWList
>>> handle = open("keywlist.txt")
>>> records = KeyWList.parse(handle)
>>> for record in records:
...     print(record["ID"])
...     print(record["DE"])
...

这将打印

2Fe-2S.
Protein which contains at least one 2Fe-2S iron-sulfur cluster: 2 iron atoms
complexed to 2 inorganic sulfides and 4 sulfur atoms of cysteines from the
protein.
...

解析 Prosite 记录

Prosite 是一个包含蛋白质结构域、蛋白质家族、功能位点以及识别它们的模式和概要文件的数据库。Prosite 与 Swiss-Prot 平行开发。在 Biopython 中,Prosite 记录由 Bio.ExPASy.Prosite.Record 类表示,其成员对应于 Prosite 记录中的不同字段。

通常,Prosite 文件可以包含多个 Prosite 记录。例如,完整的 Prosite 记录集可以从 ExPASy FTP 站点 下载为单个文件 (prosite.dat),其中包含 2073 个记录(2007 年 12 月 4 日发布的 20.24 版)。要解析此类文件,我们再次使用迭代器

>>> from Bio.ExPASy import Prosite
>>> handle = open("myprositefile.dat")
>>> records = Prosite.parse(handle)

现在我们可以逐个获取记录并打印一些信息。例如,使用包含完整 Prosite 数据库的文件,我们会发现

>>> from Bio.ExPASy import Prosite
>>> handle = open("prosite.dat")
>>> records = Prosite.parse(handle)
>>> record = next(records)
>>> record.accession
'PS00001'
>>> record.name
'ASN_GLYCOSYLATION'
>>> record.pdoc
'PDOC00001'
>>> record = next(records)
>>> record.accession
'PS00004'
>>> record.name
'CAMP_PHOSPHO_SITE'
>>> record.pdoc
'PDOC00004'
>>> record = next(records)
>>> record.accession
'PS00005'
>>> record.name
'PKC_PHOSPHO_SITE'
>>> record.pdoc
'PDOC00005'

等等。如果你对 Prosite 记录的数量感兴趣,你可以使用

>>> from Bio.ExPASy import Prosite
>>> handle = open("prosite.dat")
>>> records = Prosite.parse(handle)
>>> n = 0
>>> for record in records:
...     n += 1
...
>>> n
2073

要从句柄中读取一个 Prosite,你可以使用 read 函数

>>> from Bio.ExPASy import Prosite
>>> handle = open("mysingleprositerecord.dat")
>>> record = Prosite.read(handle)

如果找不到 Prosite 记录,或者找到多个 Prosite 记录,此函数都会引发 ValueError。

解析 Prosite 文档记录

在上面的 Prosite 示例中,record.pdoc 访问号 'PDOC00001''PDOC00004''PDOC00005' 等等引用 Prosite 文档。Prosite 文档记录可从 ExPASy 获取,作为单个文件,以及包含所有 Prosite 文档记录的一个文件 (prosite.doc)。

我们使用 Bio.ExPASy.Prodoc 中的解析器来解析 Prosite 文档记录。例如,要创建 Prosite 文档记录的所有访问号列表,你可以使用

>>> from Bio.ExPASy import Prodoc
>>> handle = open("prosite.doc")
>>> records = Prodoc.parse(handle)
>>> accessions = [record.accession for record in records]

同样,提供了 read() 函数来从句柄中读取一个 Prosite 文档记录。

解析 Enzyme 记录

ExPASy 的 Enzyme 数据库是关于酶命名法的资料库。典型的 Enzyme 记录如下所示

ID   3.1.1.34
DE   Lipoprotein lipase.
AN   Clearing factor lipase.
AN   Diacylglycerol lipase.
AN   Diglyceride lipase.
CA   Triacylglycerol + H(2)O = diacylglycerol + a carboxylate.
CC   -!- Hydrolyzes triacylglycerols in chylomicrons and very low-density
CC       lipoproteins (VLDL).
CC   -!- Also hydrolyzes diacylglycerol.
PR   PROSITE; PDOC00110;
DR   P11151, LIPL_BOVIN ;  P11153, LIPL_CAVPO ;  P11602, LIPL_CHICK ;
DR   P55031, LIPL_FELCA ;  P06858, LIPL_HUMAN ;  P11152, LIPL_MOUSE ;
DR   O46647, LIPL_MUSVI ;  P49060, LIPL_PAPAN ;  P49923, LIPL_PIG   ;
DR   Q06000, LIPL_RAT   ;  Q29524, LIPL_SHEEP ;
//

在此示例中,第一行显示了脂蛋白脂肪酶的 EC(酶委员会)号(第二行)。脂蛋白脂肪酶的别名是“清除因子脂肪酶”、“二酰基甘油脂肪酶”和“二甘油酯脂肪酶”(第 3 到 5 行)。以“CA”开头的行显示了这种酶的催化活性。以“CC”开头的行是注释行。“PR”行显示了 Prosite 文档记录的引用,而“DR”行显示了 Swiss-Prot 记录的引用。并非所有这些条目都一定存在于 Enzyme 记录中。

在 Biopython 中,Enzyme 记录由 Bio.ExPASy.Enzyme.Record 类表示。此记录从 Python 字典派生,其键对应于 Enzyme 文件中使用的两位字母代码。要读取包含一个 Enzyme 记录的 Enzyme 文件,请使用 Bio.ExPASy.Enzyme 中的 read 函数

>>> from Bio.ExPASy import Enzyme
>>> with open("lipoprotein.txt") as handle:
...     record = Enzyme.read(handle)
...
>>> record["ID"]
'3.1.1.34'
>>> record["DE"]
'Lipoprotein lipase.'
>>> record["AN"]
['Clearing factor lipase.', 'Diacylglycerol lipase.', 'Diglyceride lipase.']
>>> record["CA"]
'Triacylglycerol + H(2)O = diacylglycerol + a carboxylate.'
>>> record["PR"]
['PDOC00110']
>>> record["CC"]
['Hydrolyzes triacylglycerols in chylomicrons and very low-density lipoproteins
(VLDL).', 'Also hydrolyzes diacylglycerol.']
>>> record["DR"]
[['P11151', 'LIPL_BOVIN'], ['P11153', 'LIPL_CAVPO'], ['P11602', 'LIPL_CHICK'],
['P55031', 'LIPL_FELCA'], ['P06858', 'LIPL_HUMAN'], ['P11152', 'LIPL_MOUSE'],
['O46647', 'LIPL_MUSVI'], ['P49060', 'LIPL_PAPAN'], ['P49923', 'LIPL_PIG'],
['Q06000', 'LIPL_RAT'], ['Q29524', 'LIPL_SHEEP']]

如果找不到 Enzyme 记录,或者找到多个 Enzyme 记录,read 函数都会引发 ValueError。

完整的 Enzyme 记录集可以从 ExPASy FTP 站点 下载为单个文件 (enzyme.dat),其中包含 4877 个记录(2009 年 3 月 3 日发布)。要解析此类包含多个 Enzyme 记录的文件,请使用 Bio.ExPASy.Enzyme 中的 parse 函数获取迭代器

>>> from Bio.ExPASy import Enzyme
>>> handle = open("enzyme.dat")
>>> records = Enzyme.parse(handle)

现在我们可以逐个遍历这些记录。例如,我们可以创建所有可用的 Enzyme 记录的 EC 号列表

>>> ecnumbers = [record["ID"] for record in records]

访问 ExPASy 服务器

Swiss-Prot、Prosite 和 Prosite 文档记录可以从 ExPASy 网站服务器下载 https://www.expasy.org。ExPASy 提供四种查询方式

get_prodoc_entry

以 HTML 格式下载 Prosite 文档记录

get_prosite_entry

以 HTML 格式下载 Prosite 记录

get_prosite_raw

以原始格式下载 Prosite 或 Prosite 文档记录

get_sprot_raw

以原始格式下载 Swiss-Prot 记录

要从 Python 脚本访问此 Web 服务器,我们使用 Bio.ExPASy 模块。

检索 Swiss-Prot 记录

假设我们正在研究兰花的查尔酮合酶(参见部分 一个使用示例,了解为什么我们会对兰花感兴趣)。查尔酮合酶参与植物中的黄酮类生物合成,黄酮类生物合成产生许多酷炫的东西,例如色素颜色和紫外线防护剂。

如果你在 Swiss-Prot 上搜索,你可以找到三种兰花查尔酮合酶蛋白,ID 号为 O23729、O23730、O23731。现在,让我们编写一个脚本,获取这些蛋白并解析出一些有趣的信息。

首先,我们使用 Bio.ExPASyget_sprot_raw() 函数获取记录。这个函数非常棒,因为你可以向它提供一个 ID,然后它会返回一个指向原始文本记录的句柄(没有 HTML 要处理!)。然后我们可以使用 Bio.SwissProt.read 来提取 Swiss-Prot 记录,或者使用 Bio.SeqIO.read 来获取 SeqRecord。以下代码实现了我的描述

>>> from Bio import ExPASy
>>> from Bio import SwissProt

>>> accessions = ["O23729", "O23730", "O23731"]
>>> records = []

>>> for accession in accessions:
...     handle = ExPASy.get_sprot_raw(accession)
...     record = SwissProt.read(handle)
...     records.append(record)
...

如果提供给 ExPASy.get_sprot_raw 的登录号不存在,那么 SwissProt.read(handle) 将会引发 ValueError。你可以捕获 ValueException 异常来检测无效的登录号

>>> for accession in accessions:
...     handle = ExPASy.get_sprot_raw(accession)
...     try:
...         record = SwissProt.read(handle)
...     except ValueException:
...         print("WARNING: Accession %s not found" % accession)
...     records.append(record)
...

使用 UniProt 搜索

现在,你可能会注意到,我事先知道记录的登录号。确实,get_sprot_raw() 需要条目名称或登录号。当你没有这些信息时,你可以使用 UniProt 来搜索它们。你也可以使用 UniProt 包来以编程方式搜索蛋白质。

例如,让我们搜索来自特定生物体(生物体 ID:2697049)的已审查蛋白质。我们可以使用以下代码来实现

>>> from Bio import UniProt

>>> query = "(organism_id:2697049) AND (reviewed:true)"
>>> results = list(UniProt.search(query))

The UniProt.search 方法返回一个搜索结果的迭代器。迭代器每次返回一个结果,并在需要时从 UniProt 获取更多结果,直到返回所有结果。我们可以有效地从这个迭代器创建列表,因为这个查询只返回少量结果(在编写本文时为 17 个)。

让我们尝试一个返回更多结果的搜索。在编写本文时,查询“Insulin AND (reviewed:true)”有 5,147 个结果。我们可以使用切片来获取前 50 个结果的列表。

>>> from Bio import UniProt
>>> from itertools import islice

>>> query = "Insulin AND (reviewed:true)"
>>> results = UniProt.search(query, batch_size=50)[:50]

你可以使用 len 方法获取搜索结果的总数(无论批次大小)。

>>> from Bio import UniProt

>>> query = "Insulin AND (reviewed:true)"
>>> result_iterator = UniProt.search(query, batch_size=0)
>>> len(result_iterator)
5147

检索 Prosite 和 Prosite 文档记录

Prosite 和 Prosite 文档记录可以以 HTML 格式或原始格式检索。要使用 Biopython 解析 Prosite 和 Prosite 文档记录,你应该以原始格式检索记录。但是,出于其他目的,你可能对这些记录的 HTML 格式感兴趣。

要以原始格式检索 Prosite 或 Prosite 文档记录,请使用 get_prosite_raw()。例如,要下载 Prosite 记录并以原始文本格式打印它,请使用

>>> from Bio import ExPASy
>>> handle = ExPASy.get_prosite_raw("PS00001")
>>> text = handle.read()
>>> print(text)

要检索 Prosite 记录并将其解析为 Bio.Prosite.Record 对象,请使用

>>> from Bio import ExPASy
>>> from Bio import Prosite
>>> handle = ExPASy.get_prosite_raw("PS00001")
>>> record = Prosite.read(handle)

相同的函数可用于检索 Prosite 文档记录并将其解析为 Bio.ExPASy.Prodoc.Record 对象

>>> from Bio import ExPASy
>>> from Bio.ExPASy import Prodoc
>>> handle = ExPASy.get_prosite_raw("PDOC00001")
>>> record = Prodoc.read(handle)

对于不存在的登录号,ExPASy.get_prosite_raw 返回一个指向空字符串的句柄。当遇到空字符串时,Prosite.readProdoc.read 将会引发 ValueError。你可以捕获这些异常来检测无效的登录号。

函数 get_prosite_entry()get_prodoc_entry() 用于以 HTML 格式下载 Prosite 和 Prosite 文档记录。要创建显示一个 Prosite 记录的网页,你可以使用

>>> from Bio import ExPASy
>>> handle = ExPASy.get_prosite_entry("PS00001")
>>> html = handle.read()
>>> with open("myprositerecord.html", "w") as out_handle:
...     out_handle.write(html)
...

类似地,对于 Prosite 文档记录,你可以使用

>>> from Bio import ExPASy
>>> handle = ExPASy.get_prodoc_entry("PDOC00001")
>>> html = handle.read()
>>> with open("myprodocrecord.html", "w") as out_handle:
...     out_handle.write(html)
...

对于这些函数,无效的登录号会以 HTML 格式返回错误消息。

扫描 Prosite 数据库

ScanProsite 允许你通过提供 UniProt 或 PDB 序列标识符或序列本身来在线扫描蛋白质序列以查找 Prosite 数据库。有关 ScanProsite 的更多信息,请参阅 ScanProsite 文档 以及 ScanProsite 的编程访问文档

你可以使用 Biopython 的 Bio.ExPASy.ScanProsite 模块从 Python 扫描 Prosite 数据库。此模块既可以帮助你以编程方式访问 ScanProsite,也可以解析 ScanProsite 返回的结果。要扫描以下蛋白质序列中的 Prosite 模式

MEHKEVVLLLLLFLKSGQGEPLDDYVNTQGASLFSVTKKQLGAGSIEECAAKCEEDEEFT
CRAFQYHSKEQQCVIMAENRKSSIIIRMRDVVLFEKKVYLSECKTGNGKNYRGTMSKTKN

你可以使用以下代码

>>> sequence = (
...     "MEHKEVVLLLLLFLKSGQGEPLDDYVNTQGASLFSVTKKQLGAGSIEECAAKCEEDEEFT"
...     "CRAFQYHSKEQQCVIMAENRKSSIIIRMRDVVLFEKKVYLSECKTGNGKNYRGTMSKTKN"
... )
>>> from Bio.ExPASy import ScanProsite
>>> handle = ScanProsite.scan(seq=sequence)

通过执行 handle.read(),你可以获取以原始 XML 格式呈现的搜索结果。相反,让我们使用 Bio.ExPASy.ScanProsite.read 将原始 XML 解析为 Python 对象

>>> result = ScanProsite.read(handle)
>>> type(result)
<class 'Bio.ExPASy.ScanProsite.Record'>

一个 Bio.ExPASy.ScanProsite.Record 对象是从列表派生的,列表中的每个元素都存储一个 ScanProsite 命中。此对象还存储命中次数以及 ScanProsite 返回的搜索序列次数。此 ScanProsite 搜索产生了六次命中

>>> result.n_seq
1
>>> result.n_match
1
>>> len(result)
1
>>> result[0]
{'sequence_ac': 'USERSEQ1', 'start': 16, 'stop': 98, 'signature_ac': 'PS50948', 'score': '8.873', 'level': '0'}

其他 ScanProsite 参数可以作为关键字参数传递;有关更多信息,请参阅 ScanProsite 的编程访问文档。例如,传递 lowscore=1 以包含低级别分数匹配,让我们找到一个额外的命中

>>> handle = ScanProsite.scan(seq=sequence, lowscore=1)
>>> result = ScanProsite.read(handle)
>>> result.n_match
2