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.ExPASy
的 get_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.read
和 Prodoc.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